C#在xml

时间:2016-03-04 22:00:36

标签: c# xml

我正在尝试为现有代码添加代码。我有两个xmls以下:

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必须如下所示。这里的规则是在Out和In xmls中检查StudentID。如果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。

更新

非常感谢@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);

    }
}

1 个答案:

答案 0 :(得分:1)

这会将两个集合都设置为一个匿名对象List,进行比较,并为您提供一组尚不存在的匿名对象,您可以将这些对象添加到out 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
            }
        }