XmlDocument
是其节点的工厂,所以你必须这样做:
XmlNode newNode = document.CreateNode(XmlNodeType.Element, "product", "");
或者它的快捷方式:
XmlNode newNode = document.CreateElement("product");
然后将新创建的节点添加到其父节点:
node.ParentNode.AppendChild(newNode);
如果必须处理添加的节点,则必须明确执行:节点列表是匹配搜索条件的节点的快照,则不会动态更新。只需调用insertIntoTable()
添加的节点:
insertIntoTable(node.ParentNode.AppendChild(newNode));
如果您的代码有很大不同,您可能需要进行一些重构以使此过程成为两步批处理(首先搜索要添加的节点,然后将它们全部处理)。当然,您甚至可以采用完全不同的方法(例如将节点从列表复制XmlNodeList
到列表中,然后将它们添加到两个列表中)。
假设这已经足够(并且您不需要重构)让我们将所有内容放在一起:
foreach (var node in productsXml.SelectNodes("/portfolio/products/product"))
{
if (node.Attributes["name"].InnertText.StartsWith("PB_"))
{
XmlNode newNode = document.CreateElement("product");
insertIntoTable(node.ParentNode.AppendChild(newNode));
}
// Move this before previous IF in case it must be processed
// before added node
insertIntoTable(node);
}
重构
重构时间(如果你有一个 200 行的函数,你真的需要它,比我在这里展示的要多得多)。第一种方法,即使不是很有效:
var list = productsXml
.SelectNodes("/portfolio/products/product")
.Cast<XmlNode>();
.Where(x.Attributes["name"].InnertText.StartsWith("PB_"));
foreach (var node in list)
node.ParentNode.AppendChild(document.CreateElement("product"));
foreach (var node in productsXml.SelectNodes("/portfolio/products/product"))
insertIntoTable(node); // Or your real code
如果你不喜欢两遍方法,你可以ToList()
这样使用:
var list = productsXml
.SelectNodes("/portfolio/products/product")
.Cast<XmlNode>()
.ToList();
for (int i=0; i < list.Count; ++i)
{
var node = list[i];
if (node.Attributes["name"].InnertText.StartsWith("PB_"))
list.Add(node.ParentNode.AppendChild(document.CreateElement("product"))));
insertIntoTable(node);
}
请注意,在第二个示例中,使用for
代替foreach
是强制性的,因为您在循环中更改了集合。请注意,您甚至可以将原始XmlNodeList
对象保留在原处...