C# 在 xml 中添加节点

本文关键字:添加 节点 xml | 更新日期: 2023-09-27 18:37:23

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

出.xml

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

在.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 必须如下所示。这里的规则是检查学生ID在外面和在xmls。如果 Out xml 没有它,而 In xml 有它,则将其添加到 Out.xml 在现有元素的末尾。

出.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# 添加节点/元素。我正在寻找如何比较两个 xml,然后将节点/元素添加到缺少这些节点/元素的节点/元素中。我在这里的问题是,一个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);
    }
}

C# 在 xml 中添加节点

这会将

这两个集投影到一个匿名对象列表中,进行比较,并为您提供一组尚不存在的匿名对象,您可以通过这些对象添加到 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
    }
}