問題は、sitemapindex
要素がデフォルトの名前空間を定義していることです。ノードを選択するときに名前空間を指定する必要があります。指定しないと、ノードが見つかりません。例えば:
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", "http://www.sitemaps.org/schemas/sitemap/0.9");
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);
通常、を使用するXmlNameSpaceManager
場合は、プレフィックスを空の文字列のままにして、その名前空間をデフォルトの名前空間にすることを指定できます。したがって、次のようなことができると思います。
// WON'T WORK
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("", "http://www.sitemaps.org/schemas/sitemap/0.9"); //Empty prefix
XmlNodeList xnList = xml.SelectNodes("/sitemapindex/sitemap", manager); //No prefixes in XPath
ただし、そのコードを試してみると、一致するノードが見つからないことがわかります。これは、XPath 1.0(XmlDocumentが実装するもの)では、名前空間が指定されていない場合、デフォルトの名前空間ではなく、常にnull名前空間を使用するためです。したがって、でデフォルトの名前空間を指定するかどうかは関係ありませXmlNamespaceManager
ん。とにかく、XPathでは使用されません。公式XPath仕様から関連する段落を引用するには:
ノードテストのQNameは、式コンテキストからの名前空間宣言を使用して、展開された名前に展開されます。これは、開始タグと終了タグの要素タイプ名に対して拡張が行われるのと同じ方法ですが、xmlnsで宣言されたデフォルトの名前空間が使用されない点が異なります。QNameにプレフィックスがない場合、名前空間URIはnullになります(これは同じです)。属性名が展開される方法)。QNameに、式コンテキストに名前空間宣言がないプレフィックスがある場合はエラーになります。
したがって、読み取っている要素が名前空間に属している場合、XPathステートメントに名前空間プレフィックスを含めることを避けられません。ただし、コードに名前空間URIをわざわざ入れたくない場合は、XmlDocument
オブジェクトを使用してルート要素のURIを返すことができます。この場合はこれが必要です。例えば:
XmlDocument xml = new XmlDocument();
xml.Load("sitemap.xml");
XmlNamespaceManager manager = new XmlNamespaceManager(xml.NameTable);
manager.AddNamespace("s", xml.DocumentElement.NamespaceURI); //Using xml's properties instead of hard-coded URI
XmlNodeList xnList = xml.SelectNodes("/s:sitemapindex/s:sitemap", manager);