2017-06-06 8 views
1

から、私は与えられた構造を持つXMLがあります(ただし、指定されたIDを持つどの要素が存在しない場合のみ)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> 

をそして私は、このテンプレートを使用して、別の要素を挿入します:

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

だから私のアイデアはstringとしてテンプレートをロードし、与えられているものは何でもにより$ID$$VALUE$を交換しました。次に、この文字列をXmlDocumentFragmentとして解析します。そして、このIDを持つ要素が既に存在するかどうかを確認する必要があります。存在しない場合にのみ、新しい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タグを追加すると、多くの仕事への道になり、より複雑なシナリオを持っているので、 。

+0

アプローチを最適化することができます。まずフラグメント要素を作成して元のXMLを検索する代わりに、元のXMLを検索してから、作成と挿入を行うことができます。 – Gururaj

+0

私は知っていますが、それは私の問題で私を助けません – danielspaniol

答えて

1

条件は、内部ブラケットも、なるように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 
      { 
      } 
     } 
    } 

をこれを達成することができ、XPathのこの

+0

これは、私が言ったように、テンプレート文字列を使いたいので動作しません。私は実際にはるかに大きなネストされたXML文書を持っており、この目的のためだけに10個のPOCOを書いたくありません。 – danielspaniol

+0

IDで検証するだけで、ファイルに追加する前に これは –

+0

を修正する可能性があります。あなたの要件に応じてコードを更新する必要がある要素を10個追加しました。 –

関連する問題