2017-06-06 100 views
1

我有给定结构的XML:C# - 从字符串模板中插入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); 
} 

而且我真的想用一个模板文件,因为我其实有更复杂的场景中添加这些XML标签在C#中没有一个模板字符串是办法不多的工作。

+0

您可以优化您的方法。先不创建片段元素并搜索原始XML,您可以先搜索原始XML,然后搜索创建和插入。 – Gururaj

+0

我知道,但这并不能帮助我解决问题 – danielspaniol

回答

1

条件中的XPath必须是括号内,所以改写的XPath为:

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

你可以XMLSerialization和反序列化的帮助实现这一目标,

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 
      { 
      } 
     } 
    } 

这将作为你的预期,试试这个

+0

这不会起作用,因为正如我所说的我想使用模板字符串。实际上我有更大的嵌套XML文档,不想为此写10个POCO。 – danielspaniol

+0

你只是想通过ID验证,然后将其添加到文件, 这可能会修复 –

+0

只是暂时我已经添加了10个元素,您需要根据您的要求更新代码 –