XmlDocument
はそのノードのファクトリであるため、これを行う必要があります。
XmlNode newNode = document.CreateNode(XmlNodeType.Element, "product", "");
またはそのショートカット:
XmlNode newNode = document.CreateElement("product");
次に、新しく作成されたノードをその親に追加するには:
node.ParentNode.AppendChild(newNode);
追加されたノードを処理する必要がある場合は、明示的に処理する必要があります。ノード リストは、検索条件に一致したノードのスナップショットであり、動的に更新されません。insertIntoTable()
追加されたノードを呼び出すだけです:
insertIntoTable(node.ParentNode.AppendChild(newNode));
コードが大きく異なる場合は、このプロセスを 2 ステップのバッチにするために少しリファクタリングが必要になる場合があります (最初に追加するノードを検索し、次にそれらすべてを処理します)。もちろん、完全に異なるアプローチに従うこともできます (たとえば、ノードを List からコピー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
2 パス アプローチが気に入らない場合は、次のように使用できます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);
}
2 番目の例では、ループ内でコレクションを変更するため、for
代わりにの使用が必須であることに注意してください。元のオブジェクトをforeach
そのままにしておくこともできることに注意してください...XmlNodeList