1. ホーム
  2. .net

なぜXmlNamespaceManagerが必要なのですか?

2023-11-25 08:31:54

疑問点

私は、次のようなことを思いつきました。 なぜ -- は、少なくとも.Net Frameworkでは XmlNamespaceManager を使う必要があるのか(あるいは、かなり無骨で冗長な [local-name()=... XPath 述語/関数/何でも) を処理するために、XPath クエリを実行する際に I する 名前空間がなぜ必要なのか、少なくとも有益なのかは理解していますが なぜ はそんなに複雑なのでしょうか?

単純なXML文書(名前空間なし)を問い合わせるには...

<?xml version="1.0" encoding="ISO-8859-1"?>
<rootNode>
   <nodeName>Some Text Here</nodeName>
</rootNode>

...のようなものを使うことができます。 doc.SelectSingleNode("//nodeName") (これは <nodeName>Some Text Here</nodeName> )

ミステリーその1 : 私の最初の悩みは -- もし私が正しく理解しているならば、単に親/ルートタグに名前空間参照を追加するだけで、(子ノードタグの一部として使用されているかどうかにかかわらず)このようなことができます。

<?xml version="1.0" encoding="ISO-8859-1"?>
<rootNode xmlns="http://example.com/xmlns/foo">
   <nodeName>Some Text Here</nodeName>
</rootNode>

...同じ結果を得るために、数行の余分なコードが必要です。

Dim nsmgr As New XmlNamespaceManager(doc.NameTable)
nsmgr.AddNamespace("ab", "http://example.com/xmlns/foo")
Dim desiredNode As XmlNode = doc.SelectSingleNode("//ab:nodeName", nsmgr)

...本来は存在しない接頭辞を夢想する(" ab ")を使って、接頭辞さえ使っていないノードを見つけることです。 これはどのように意味があるのでしょうか? 何が(概念的に)間違っているかというと doc.SelectSingleNode("//nodeName") ?

ミステリーその2 : では、接頭辞を使用するXML文書があるとします。

<?xml version="1.0" encoding="ISO-8859-1"?>
<rootNode xmlns:cde="http://example.com/xmlns/foo" xmlns:feg="http://example.com/xmlns/bar">
   <cde:nodeName>Some Text Here</cde:nodeName>
   <feg:nodeName>Some Other Value</feg:nodeName>
   <feg:otherName>Yet Another Value</feg:otherName>
</rootNode>

... もし私が正しく理解していれば、両方の名前空間を XmlNamespaceManager に追加しなければなりません。

Dim nsmgr As New XmlNamespaceManager(doc.NameTable)
nsmgr.AddNamespace("cde", "http://example.com/xmlns/foo")
nsmgr.AddNamespace("feg", "http://example.com/xmlns/bar")
Dim desiredNode As XmlNode = doc.SelectSingleNode("//feg:nodeName", nsmgr)

... この場合、なぜ(概念的に)名前空間マネージャーが必要なのでしょうか?

******以下のコメントにREDACTED*****です。

編集を追加しました。 私の修正され洗練された質問は、私が大多数と信じているケースにおけるXmlNamespaceManagerの明白な冗長性と、プレフィックスとURIのマッピングを指定するための名前空間マネージャの使用に基づいています。

名前空間プレフィックス ("cde") を名前空間 URI に直接マッピングする場合 (" http://example.com/xmlns/foo ")がソース文書で明示的に記述されている場合。

...<rootNode xmlns:cde="http://example.com/xmlns/foo"...

プログラマがクエリを作成する前にそのマッピングを再作成する概念的な必要性は何でしょうか?

どのように解決するのですか?

基本的なポイントは Kev、上記 によって指摘されたように)、名前空間 URI は名前空間の重要な部分であり、むしろ名前空間プレフィックスよりも、プレフィックスは "arbitrary convenience" であるということです。

なぜ名前空間マネージャが必要なのかというと、ドキュメントを使用してそれを解決する魔法があるのではなく、2 つの理由が考えられます。

理由 1

もし、あなたの例のように、documentElementに名前空間宣言を追加することだけが許されるなら、selectSingleNodeが定義されたものをただ使うのは確かに些細なことでしょう。

しかし、名前空間接頭辞は文書内のどの要素にも定義でき、また名前空間接頭辞は文書内のどの名前空間にも一意的に束縛されるわけではありません。 次の例を見てみましょう。

<w xmlns:a="mynamespace">
  <a:x>
    <y xmlns:a="myOthernamespace">
      <z xmlns="mynamespace">
      <b:z xmlns:b="mynamespace">
      <z xmlns="myOthernamespace">
      <b:z xmlns:b="myOthernamespace">
    </y>
  </a:x>
</w>

この例では、何をしたいかというと //z , //a:z//b:z を返しますか? 外部の名前空間マネージャーなしで、どのようにそれを表現するのでしょうか?

理由2

使用されている名前空間プレフィックスについて何も知る必要がなく、同等のあらゆる文書に対して同じ XPath 式を再利用することができます。

myXPathExpression = "//z:y"
doc1.selectSingleNode(myXPathExpression);
doc2.selectSingleNode(myXPathExpression);

doc1です。

<x>
  <z:y xmlns:z="mynamespace" />
</x>

doc2です。

<x xmlns"mynamespace">
  <y>
</x>

名前空間マネージャーなしでこの後者の目標を達成するためには、それぞれのドキュメントを検査し、それぞれのドキュメントに対してカスタム XPath 式を構築する必要があります。