C# - 从String模板插入XML元素

时间:2017-06-06 10:53:13

标签: c# xml

我有一个具有给定结构的xml:

<ArrayOfElement>
    <Element>
        <ID>1</ID>
        <Value>Value1</Value>
    </Element>
    <Element>
        <ID>2</ID>
        <Value>Value2</Value>
    </Element>
    <Element>
        <ID>3</ID>
        <Value>Value3</Value>
    </Element>
    ...
</ArrayOfElement>

我想用这个模板插入另一个元素(但是只有当没有给定ID的元素时才存在):

<Element>
    <ID>$ID$</ID>
    <Value>$VALUE$</Value>
</Element>

所以我的想法是将模板加载为string,并将$ID$$VALUE$替换为给定的内容。然后我将此字符串解析为XmlDocumentFragment。然后我需要查看具有此ID的元素是否已经存在,并且只有在没有的时候我才想插入新的元素。
但我不知道如何找到一个存在。

我目前的做法是:

// Load the XML with the ArrayOfElement
var allElements = new XmlDocument();
allElements.Load("file.xml");

// Load the template and insert id and value
var xmlTemplate = File.ReadAllText("template.xml");
var fragment = allElements.CreateDocumentFragment();
fragment.InnerXml = xmlTemplate.Replace("$ID$", _id).Replace("$VALUE$", _value);

// This does not work since it will throw an exception if none is found:
if (allElements.SelectNodes("ArrayOfElement/Element/ID/text() = '" + _id + "'").Count == 0)
{
    allElements.appendChild(fragment);
}

另外,我真的想要使用模板文件,因为我实际上有更复杂的场景,在没有模板字符串的情况下在C#中添加这些XML-Tags会有很多工作。

2 个答案:

答案 0 :(得分:1)

您可以借助XMLSerialization和Deserialization,

来实现这一目标
public class SerializeDeserialize
    {
        [XmlRoot(ElementName = "ArraofElements")]
        public class ArraofElements
        {
            private List<Element> elm = new List<Element>();

            [XmlElement("Module")]
            public List<Element> Elm
            {
                get { return elm; }
                set { elm = value; }
            }
        }

        public class Element
        {
            [XmlElement("ID")]
            public int id { get; set; }

            [XmlElement("Value")]
            public string value { get; set; }
        }

        ArraofElements dnl = new ArraofElements();

        public void Serialize(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                var temp = dnl.Elm.FirstOrDefault(x => x.id == i);
                if (temp == null)
                    temp = new Element();

                temp.id = i;
                temp.value = "Element " + i;

                dnl.Elm.Add(temp);
            }

            try
            {
                // to Save columnorders to the file
                var serializer = new XmlSerializer(typeof(ArraofElements));
                var ns = new XmlSerializerNamespaces();
                ns.Add("", "");


                using (TextWriter writer = new StreamWriter(@"your path"))
                {
                    serializer.Serialize(writer, dnl, ns);
                }

            }
            catch { }
        }

        public void Deserialize(object sender, EventArgs e)
        {
            try
            {
                if (File.Exists(@"your path"))
                {

                    var deserializer = new XmlSerializer(typeof(ArraofElements));
                    using (TextReader reader = new StreamReader(@"your path"))
                    {
                        dnl = (ArraofElements)deserializer.Deserialize(reader);
                    }

                }
            }
            catch
            {
            }
        }
    }

这将按预期工作,试试这个

答案 1 :(得分:1)

XPath中的条件必须在括号内,因此将xpath重写为:

if (allElements.SelectNodes("ArrayOfElement/Element/ID[text()='" + _id + "']").Count == 0)