我正在尝试将节点添加到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 :(得分:2)
您需要递归添加节点,检查代码上的注释以获取更多详细信息。
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);
}
}
答案 1 :(得分: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);
}
答案 2 :(得分: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);
}