SelectNodes と GetElementsByTagName
-
22-09-2019 - |
質問
SelectNodes と GetElementsByTagName の主な違いは何ですか。
解決
SELECTNODES の.NETで/ のXPath の発現のための一致するノードのリストを取得MSXML固有の方法。 XPathには、タグ名で要素を選択することができますだけでなく、他の、より複雑な選択ルールの多くを行うことができます。
getElementByTagName の多くの言語で利用可能なDOMレベル1のコアの標準的な方法である(しかし、で綴ら.NETでの資本G
)。それだけで、タグ名で要素を選択します。あなたは、タグ名a
またはそのような巧妙なものと他の要素内のタグ名b
を持つ特定の属性を持つ要素、または要素を選択することを求めることはできません。それはより速く、より簡単な、そしていくつかの環境で古いです。
他のヒント
SelectNodes
パラメータとしてのXPath の式を取り、一致その発現することをすべてのノードを返します。
GetElementsByTagName
パラメータとしてタグ名を取り、その名前を持つすべてのタグを返します。
SelectNodes
呼び出しとして任意のGetElementsByTagName
コールを書くことはできませんが、として SelectNodes
は、したがって、より表現です。 XPathは、XMLノードのセットを表す名前だけよりも、フィルタリングのより多くの方法を提供する非常に強力な方法です。 XPathは、例えば、同様のタグ名、属性名、内部コンテンツおよびタグの子どもたちにさまざまな集約関数でフィルタリングすることができます。
SelectNodes() は、ドキュメント オブジェクト モデル (DOM) に対する Microsoft の拡張機能です (msdn)。Welbog らによって言及されている SelectNodes は XPath 式を受け取ります。XMLノードの削除が必要な場合のGetElementsByTagName()との違いについて触れておきたいと思います。
ユーザーが提供した答えとコード チルベルト で msdn フォーラム
次のテストでは、同じ機能 (人物ノードの削除) を実行しますが、GetElementByTagName() メソッドを使用してノードを選択することにより、違いを示します。同じオブジェクト型が返されますが、その構造は異なります。SelectNodes() は、XML ドキュメントへの参照のコレクションです。つまり、参照リストに影響を与えることなく、foreach でドキュメントから削除できるということです。これは、影響を受けていないノードリストの数によって示されます。GetElementByTagName() は、ドキュメント内のノードを直接反映するコレクションです。つまり、親内の項目を削除すると、実際にはノードのコレクションに影響を与えます。これが、ノードリストを foreach で操作できず、while ループに変更する必要がある理由です。
.NET SelectNodes()
[TestMethod]
public void TestSelectNodesBehavior()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(@"<root>
<person>
<id>1</id>
<name>j</name>
</person>
<person>
<id>2</id>
<name>j</name>
</person>
<person>
<id>1</id>
<name>j</name>
</person>
<person>
<id>3</id>
<name>j</name>
</person>
<business></business>
</root>");
XmlNodeList nodeList = doc.SelectNodes("/root/person");
Assert.AreEqual(5, doc.FirstChild.ChildNodes.Count, "There should have been a total of 5 nodes: 4 person nodes and 1 business node");
Assert.AreEqual(4, nodeList.Count, "There should have been a total of 4 nodes");
foreach (XmlNode n in nodeList)
n.ParentNode.RemoveChild(n);
Assert.AreEqual(1, doc.FirstChild.ChildNodes.Count, "There should have been only 1 business node left in the document");
Assert.AreEqual(4, nodeList.Count, "There should have been a total of 4 nodes");
}
.NET GetElementsByTagName()
[TestMethod]
public void TestGetElementsByTagNameBehavior()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml(@"<root>
<person>
<id>1</id>
<name>j</name>
</person>
<person>
<id>2</id>
<name>j</name>
</person>
<person>
<id>1</id>
<name>j</name>
</person>
<person>
<id>3</id>
<name>j</name>
</person>
<business></business>
</root>");;
XmlNodeList nodeList = doc.GetElementsByTagName("person");
Assert.AreEqual(5, doc.FirstChild.ChildNodes.Count, "There should have been a total of 5 nodes: 4 person nodes and 1 business node");
Assert.AreEqual(4, nodeList.Count, "There should have been a total of 4 nodes");
while (nodeList.Count > 0)
nodeList[0].ParentNode.RemoveChild(nodeList[0]);
Assert.AreEqual(1, doc.FirstChild.ChildNodes.Count, "There should have been only 1 business node left in the document");
Assert.AreEqual(0, nodeList.Count, "All the nodes have been removed");
}
SelectNodes() を使用して、XML ドキュメント ノードへの参照のコレクション/リストを取得します。これらの参照を使用して操作できます。ノードを削除すると、変更は XML ドキュメントに表示されますが、コレクション/参照のリストは同じです (ノードは削除されましたが、参照は null -> System.NullReferenceException を指すようになりました)。これは実装されています。XmlNodeList nodeList = GetElementsByTagName() を使用し、nodeList[i].ParentNode.RemoveChild(nodeList[i]) でノードを削除すると、nodeList 変数の参照が解放/削除されると思います。