如何以编程方式添加XmlNode的到的XmlNodeList [英] how to programmatically add XmlNode to an XmlNodeList

查看:698
本文介绍了如何以编程方式添加XmlNode的到的XmlNodeList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的产品,其价值被放到一个表中的XmlNodeList。现在我要一个新的XmlNode添加到列表中时在一定发现产品,使得在相同的循环中的新产品被视为相同,是原来的文件中的项目。这样的函数的structire并不需要改变,只要添加是下一个要处理的额外节点。 但一个XmlNode是一个抽象类,我无法弄清楚如何以编程方式创建新的节点。这可能吗?

 的XmlNodeList列表= productsXml.SelectNodes(/组合/产品/产品);

的for(int i = 0; I< list.Count;我++)
{
  XmlNode的节点=列表[我]

  如果(node.Attributes [名称]。InnertText.StartsWith(PB_))
  {
    XmlNode的newNode = ????
    list.InsertAfter(???,节点);
  }

  insertIntoTable(节点);
}
 

解决方案

的XmlDocument 是工厂的节点,所以你必须要做到这一点:

  XmlNode的newNode = document.CreateNode(XmlNodeType.Element,产品,);
 

或它的快捷方式:

  XmlNode的newNode = document.createElement方法(产品);
 

然后到新创建的节点添加到它的父:

  node.ParentNode.AppendChild(newNode);
 

如果添加的节点必须进行处理,那么你必须明确地做到这一点:节点列表是匹配的搜索条件,那么它不会被动态更新节点的快照。只需拨打 insertIntoTable()的补充节点:

  insertIntoTable(node.ParentNode.AppendChild(newNode));
 

如果您的code是很大的不同,你可能需要重构一点,使这个过程两步批(第一搜索节点添加,然后处理它们)。当然,你甚至可以采取完全不同的方法(例如抄袭的XmlNodeList 节点列表,然后将其添加到这两个列表)。

假设这就够了(而你并不需要重构),让我们把一切融合在一起:

 的foreach(在productsXml.SelectNodes(VAR节点/组合/产品/产品))
{
  如果(node.Attributes [名称]。InnertText.StartsWith(PB_))
  {
    XmlNode的newNode = document.createElement方法(产品);
    insertIntoTable(node.ParentNode.AppendChild(newNode));
  }

  //在previous移动此IF情况下,它必须进行处理
  //前加入节点
  insertIntoTable(节点);
}
 

重构

重构时间(如果你有一个200线的作用,你真的需要它,比我在这里present更多)。第一种方法,即使没有非常有效的:

  VAR列表= productsXml
    .SelectNodes(/组合/产品/产品)
    .Cast&其中; XmlNode的>();
    。凡(x.Attributes [名称] InnertText.StartsWith(PB_));

的foreach(列表中的VAR节点)
    node.ParentNode.AppendChild(使用document.createElement(产品));

的foreach(在productsXml.SelectNodes VAR节点(/组合/产品/产品))
    insertIntoTable(节点); //或者你的真实code
 

如果你不喜欢一两道接近你可以使用了ToList()是这样的:

  VAR列表= productsXml
    .SelectNodes(/组合/产品/产品)
    .Cast< XmlNode的>()
    .ToList();

的for(int i = 0; I< list.Count ++ I)
{
    VAR节点=列表[我]

    如果(node.Attributes [名称]。InnertText.StartsWith(PB_))
      list.Add(node.ParentNode.AppendChild(使用document.createElement(产品))));

    insertIntoTable(节点);
}
 

请注意,在第二个例子中使用,而不是对 的foreach 是强制性的,因为你改变内集合循环。请注意,您甚至可以保留原始的XmlNodeList 对象的地方...

I have an XmlNodeList of products whose values are put into a table. Now I want to add a new XmlNode to the list when a certain product is found so that in the same loop the new products is treated the same as the items that are originally in the file. This way the structire of the function does not need to change, just add an extra node that is processed next. But an XmlNode is an abstract class and I cant figure out how to create the new node programatically. Is this possible?

XmlNodeList list = productsXml.SelectNodes("/portfolio/products/product");

for (int i = 0; i < list.Count; i++)
{
  XmlNode node = list[i];

  if (node.Attributes["name"].InnertText.StartsWith("PB_"))
  {
    XmlNode newNode = ????
    list.InsertAfter(???, node);
  }

  insertIntoTable(node);
}

解决方案

XmlDocument is the factory for its nodes so you have to do this:

XmlNode newNode = document.CreateNode(XmlNodeType.Element, "product", "");

Or its shortcut:

XmlNode newNode = document.CreateElement("product");

Then to add newly created node to its parent:

node.ParentNode.AppendChild(newNode);

If added node must be processed then you have to do it explicitly: node list is a snapshot of nodes that matched search condition then it won't be dynamically updated. Simply call insertIntoTable() for added node:

insertIntoTable(node.ParentNode.AppendChild(newNode));

If your code is much different you may need little bit of refactoring to make this process a two step batch (first search for nodes to add and then process them all). Of course you may even follow a completely different approach (for example copying nodes from XmlNodeList to a List and then adding them to both lists).

Assuming this is enough (and you do not need refactoring) let's put everything together:

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);
}

Refactoring

Refactoring time (and if you have a 200 lines function you really need it, much more than what I present here). First approach even if not very efficient:

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

If you do not like a two passes approach you may use ToList() like this:

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);
}

Please note that in second example the use of for instead of foreach is mandatory because you change the collection within the loop. Note that you may even keep your original XmlNodeList object in place...

这篇关于如何以编程方式添加XmlNode的到的XmlNodeList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆