2017-01-22 96 views
0

我试图将节点添加到xml文件。如何将新节点添加到xml文件

XML文件:

<Students> 
<Student> 
    <Address> ... </Address> 
    <Grade> ... </Grade> 
</Student> 
    ... 
</Students> 

这里是我做了什么:

public XmlElement createNode(XmlDocument xmlDoc) 
{ 
    XmlElement trElement = xmlDoc.CreateElement("Descriptions"); 
    XmlElement textElement = xmlDoc.CreateElement("Text"); 
    textElement.SetAttribute("String", "Abcdef"); 
    textElement.SetAttribute("Language", "ENG"); 
    trElement.AppendChild(textElement); 
    return trElement; 
} 
public void doWork(string filePath) 
{ 
    XmlDocument fromXML; 
    fromXML = new XmlDocument(); 
    fromXML.Load(filePath); 
    XmlNode fromRoot = fromXML.DocumentElement; 
    foreach (XmlNode node in fromRoot.ChildNodes) 
    { 
     if (node.ChildNodes[0].Name != "Descriptions") 
     { 
      var trElement = createNode(fromXML); 
      node.InsertBefore(trElement, node.ChildNodes[0]); 
     } 
    } 
    fromXML.Save(Console.Out); 
} 

上面的代码将在节点Descriptions添加到每个Student。如何将节点Descriptions添加到xml树中更深层的其他节点?当前循环遍历学生,但没有结束,例如:Grade

+0

不会嵌套for循环完成这个例子的任务吗? –

+0

你能举个例子吗? – Sam

+0

我想你可能需要在这里递归。 –

回答

1

您需要递归添加节点,查看代码上的注释以获取更多详细信息。

public static XmlNode CreateNode(XmlDocument document) 
    { 
     XmlElement trElement = document.CreateElement("Descriptions"); 
     XmlElement textElement = document.CreateElement("Text"); 
     textElement.SetAttribute("String", "Abcdef"); 
     textElement.SetAttribute("Language", "ENG"); 
     trElement.AppendChild(textElement); 
     return trElement; 
    } 

    public static void doWork(string filePath) 
    { 
     XmlDocument fromXML; 
     fromXML = new XmlDocument(); 
     fromXML.Load(filePath); 
     XmlNode fromRoot = fromXML.DocumentElement; 
     // Start from <Student></Student> 
     foreach (XmlNode node in fromRoot.ChildNodes) 
     { 
      InsertNewNodes(node, fromXML); 
     } 
     fromXML.Save(Console.Out); 
    } 

    public static void InsertNewNodes(XmlNode root, XmlDocument document) 
    { 
     var hasDescription = false; 

     // Iterate over every first level child looking for "Descriptions" 
     foreach (XmlNode node in root.ChildNodes) 
     { 
      if (node.Name == "Descriptions") 
      { 
       hasDescription = true; 
      } 
      // recursively call InsertNewNodes 
      if (node.ChildNodes.Count > 0) 
      { 
       InsertNewNodes(node, document); 
      } 
     } 
     // Adjust the root.LastChild.NodeType criteria to only add the nodes when you want 
     // In this case I only add the Description if the subnode has Elements 
     if (!hasDescription && root.LastChild.NodeType == XmlNodeType.Element) 
     { 
      var newNode = CreateNode(document); 
      root.PrependChild(newNode); 
     } 
    } 
0

如果你只需要1级更新用的只有到那时,你可以使用嵌套的for循环是这样的:

public void doWork(string filePath) 
{ 
    XmlDocument fromXML; 
    fromXML = new XmlDocument(); 
    fromXML.Load(filePath); 
    XmlNode fromRoot = fromXML.DocumentElement; 
    foreach (XmlNode node in fromRoot.ChildNodes) 
    { 
     foreach (XmlNode childNode in node) { 
      if (childNode.Name == "Grade") 
      { 
       if (childNode.ChildNodes[0].Name != "Descriptions") 
       { 
        var trElement = createNode(fromXML); 
        childNode.InsertBefore(trElement, childNode.ChildNodes[0]); 

       } 
      } 
     } 

    } 
    fromXML.Save(Console.Out); 
} 

,但更好的方法是使用XPath,这将让你用了递归即使节点它不止一个级别

public void doWork(string filePath) 
     { 
      XmlDocument fromXML; 
      fromXML = new XmlDocument(); 
      fromXML.Load(filePath); 
      XmlNode fromRoot = fromXML.DocumentElement; 
      foreach (XmlNode node in fromRoot.SelectNodes("//Grade")) 
      { 
       if (node.ChildNodes[0].Name != "Descriptions") 
       { 
        var trElement = createNode(fromXML); 
        node.InsertBefore(trElement, node.ChildNodes[0]); 

       } 

      } 
      fromXML.Save(Console.Out); 
     } 
+0

感谢您的解决方案,它确实帮助了我。 – Sam

0

此方法对于n级数

private void HandleNode(XmlNode node, XmlDocument xmlDoc) 
    { 
     if (node.HasChildNodes) 
     { 
      foreach (XmlNode child in node.ChildNodes) 
      { 
       if (node.ChildNodes[0].Name != "Descriptions" && node.Name != "Descriptions") 
       { 
        var trElement = createNode(xmlDoc); 
        node.InsertBefore(trElement, node.ChildNodes[0]); 
       } 
       if (node.Name != "Descriptions") 
        HandleNode(child, xmlDoc); 
      } 
     } 
     else 
     { 
      var trElement = createNode(xmlDoc); 
      node.InsertBefore(trElement, node.ChildNodes[0]); 
     } 
    } 

工作,用它的doWork方法一样,

public void doWork(string filePath) 
    { 
     XmlDocument fromXML; 
     fromXML = new XmlDocument(); 
     fromXML.Load(filePath); 
     XmlNode fromRoot = fromXML.DocumentElement; 
     foreach (XmlNode node in fromRoot.ChildNodes) 
     { 
      HandleNode(node, fromXML); 
     } 
     fromXML.Save(filePath); 
    }