2016-03-04 7 views
-5

Я пытаюсь добавить свой код для уже существующего кода. У меня есть ниже двух XMLs:C# Добавить узлы в xml

out.xml

<School> 
    <Classes> 
    <Class> 
    <Students> 
     <Student SequenceNumber="1"> 
     <ID>123</ID> 
     <Name>AAA</Name> 
    </Student> 
    </Students> 
    </Class> 
</Classes> 
</School> 

in.xml

<School> 
<Classes> 
    <Class> 
    <Students> 
    <Student SequenceNumber="1"> 
     <ID>456</ID> 
     <Name>BBB</Name> 
    </Student> 
    <Student SequenceNumber="2"> 
     <ID>123</ID> 
     <Name>AAA</Name> 
    </Student> 
    <Student SequenceNumber="3"> 
     <ID>789</ID> 
     <Name>CCC</Name> 
    </Student> 
    </Students> 
    </Class> 
    </Classes> 
    </School> 

Теперь мне нужно проверить out.xml и in.xml и мой последний Out .xml должно быть как показано ниже. Правило здесь - проверка StudentID в Out и In xmls. Если Out xml не имеет его, а в xml он добавляет его в Out.xml в конце уже существующих элементов.

out.xml

<School> 
<Classes> 
<Class> 
    <Students> 
    <Student SequenceNumber="1"> 
     <ID>123</ID> 
     <Name>AAA</Name> 
    </Student> 
    <Student SequenceNumber="2"> 
     <ID>456</ID> 
     <Name>BBB</Name> 
    </Student>  
    <Student SequenceNumber="3"> 
     <ID>789</ID> 
     <Name>CCC</Name> 
    </Student> 
    </Students> 
    </Class> 
</Classes> 
</School> 

уже существующий код, как показано ниже

string inFileName = @"C:\In.xml"; 
string inXml = System.IO.File.ReadAllText(inFileName); 
var xmlReaderSource = XmlReader.Create(new StringReader(inXml)); 
var mgr = new XmlNamespaceManager(xmlReaderSource.NameTable); 
mgr.AddNamespace("m", "http://www.mismo.org/residential/2009/schemas"); 
XDocument sourceXmlDoc = XDocument.Load(xmlReaderSource); 

string outFileName = @"C:\Out.xml"; 
string outXml = System.IO.File.ReadAllText(outFileName); 
XmlDocument targetXmlDoc = new XmlDocument();   
targetXmlDoc.LoadXml(outXml); 

Я не могу изменить выше код теперь мне нужно добавить свою логику.

я добавил, как показано ниже

string xpath = @"/m:School/m:Classes/m:Class/m:Students"; 

XmlNodeList outStudentNodes = targetXmlDoc.SelectNodes(xpath + "/m:Student", namespaceManager); 

if(outStudentNodes== null || outStudentNodes.Count <= 0) 
{ 
    return; 
} 

XElement root = sourceXmlDoc.Root; 
IEnumerable<XElement> inStudentsColl = from item in root.Elements("Classes").Descendants("Class") 
              .Descendants("Students").Descendants("Student") 
          select item; 

Теперь у меня есть XmlNodeList и IEnumerble, пытаясь понять, могу ли я использовать LINQ заявление и сделать код простым для моего сравнения.

Узел: Я не спрашиваю, как добавлять узлы/элементы с помощью C#. Я ищу, как сравнить два xmls, а затем добавить узлы/элементы в тот, который не хватает этих узлов/элементов. Моя проблема здесь в том, что один xml читается как XDocument и другие, используя XmlDocument.

UPDATE

Большое спасибо @TheAnatheme. Я очень ценю это.

Я следил за тем, что TheAnatheme предложил мне, и это сработало. Я назвал ответ TheAnatheme реальным решением. Пожалуйста, см. Ниже, что я сделал в блоке foreach, чтобы, если кто-то захочет использовать, они могут ссылаться на этот пост.

string xpath = @"/m:School/m:Classes/m:Class/m:Students 
XmlNode studentsNode = targetXmlDoc.SelectSingleNode(xpath, namespaceManager); 

foreach (var element in elementsToAdd) 
{ 
    //Add Microsoft.CSharp.dll (if needed) to your project for below statement to work 
    dynamic studentElement = element as dynamic; 
    if (studentElement != null) 
    { 
     XmlElement studentXmlElement = targetXmlDoc.CreateElement("Student");        

      XmlElement studentIDXmlElement = targetXmlDoc.CreateElement("ID"); 

      studentIDXmlElement.InnerText = studentElement.ID; 

      XmlElement studentNameXmlElement = targetXmlDoc.CreateElement("Name"); 
      studentNameXmlElement .InnerText = studentElement.Name; 

      studentXmlElement.AppendChild(studentIDXmlElement); 
      studentXmlElement.AppendChild(studentNameXmlElement); 

      studentsNode.AppendChild(childElement); 

    } 
} 
+0

Это не трудно Google это: http://csharp.net-tutorials.com/xml/writing-xml-with-the- xmldocument-class/ – ManoDestra

+0

Я не вижу никакого кода, связанного с вашим вопросом ..... Просто коды loding xml file .... Вы пробовали что-нибудь? – Eser

+0

@Mano ... проблема заключается не в добавлении узлов и элементов ... Я знаю, как это сделать. Я хочу знать, как мы можем найти, какие элементы/узлы отсутствуют в Out.xml, которые присутствуют в In.xml. Я пытаюсь увидеть, что мы можем обойтись без слишком большого количества циклов for и foreach ... – Ziggler

ответ

1

Это проекты оба набора в анонимный список объектов, делает сравнение, и дает вам множество анонимных объектов, которые еще не существуют, с помощью которого вы можете добавить к из XML.

public static List<object> GetInStudents(XDocument sourceXmlDoc) 
    { 
     IEnumerable<XElement> inStudentsElements = 
     sourceXmlDoc.Root.Elements("Classes").Descendants("Class") 
        .Descendants("Students").Descendants("Student"); 

     return inStudentsElements.Select(i => 
      new { Id = i.Elements().First().Value, 
       Name = i.Elements().Last().Value }).Cast<object>().ToList(); 
    } 

    public static List<object> GetOutStudents(XmlDocument targetXmlDoc) 
    { 
     XmlNodeList outStudentsElements = targetXmlDoc.GetElementsByTagName("Students")[0].ChildNodes; 

     var outStudentsList = new List<object>(); 

     for (int i = 0; i < outStudentsElements.Count; i++) 
     { 
      outStudentsList.Add(new { Id = outStudentsElements[i].ChildNodes[0].InnerText, 
            Name = outStudentsElements[i].ChildNodes[1].InnerText }); 
     } 

     return outStudentsList; 
    } 

А вы сравните их как таковые:

 var inStudents = GetInStudents(sourceXmlDoc); 
     var outStudents = GetOutStudents(targetXmlDoc); 

     if (inStudents.SequenceEqual(outStudents)) 
     { 
      return; 
     } 
     else 
     { 
      var elementsToAdd = inStudents.Except(outStudents); 

      foreach (var element in elementsToAdd) 
      { 
       // create xmlNode with element properties, add element to xml 
      } 
     } 
+0

@ TheAnatheme .. можете ли вы, пожалуйста, дайте мне знать, как я могу читать данные внутри элемента внутри цикла foreach ... пока там это именно то, что я хочу ... Мне нужно получить данные в элементе .. создать узлы и добавить в XmlDocument ... – Ziggler

+0

@Ziggler Просто введите element.Id или element.Name. Когда вы добавляете его в XmlDocument, вам нужно будет получить последний SequenceNumber, добавить его к нему и затем увеличивать по мере добавления. Это вне вашего первоначального вопроса, и Stack Overflow не является веб-сайтом для выполнения домашней работы. Вы должны будете сделать все остальное. –

+1

@ TheAnatheme .. Я понял ... Я делаю вот так: динамический newStudentElement = элемент как динамический; string newStudentId = newStudentElement .ID; string newStudentName = newStudentElement .Name; .. Я отправлю свое полное решение, как только моя задача будет выполнена ... Большое спасибо. Ваш ответ действительно указал мне в правильном направлении ... Я отмечаю это как ответ ... – Ziggler

Смежные вопросы