空白のデフォルト名前空間で同様の問題が発生しました。この XML の例では、名前空間プレフィックスを持つ要素と、名前空間プレフィックスを持たない単一の要素 (DataBlock) が混在しています。
<src:SRCExample xmlns="urn:some:stuff:here" xmlns:src="www.test.com/src" xmlns:a="www.test.com/a" xmlns:b="www.test.com/b">
<DataBlock>
<a:DocID>
<a:IdID>7</a:IdID>
</a:DocID>
<b:Supplimental>
<b:Data1>Value</b:Data1>
<b:Data2/>
<b:Extra1>
<b:More1>Value</b:More1>
</b:Extra1>
</b:Supplimental>
</DataBlock>
</src:SRCExample>
XPath Visualizer で機能する XPath を使用しようとしましたが、私のコードでは機能しませんでした。
XmlDocument doc = new XmlDocument();
doc.Load( textBox1.Text );
XPathNavigator nav = doc.DocumentElement.CreateNavigator();
XmlNamespaceManager nsman = new XmlNamespaceManager( nav.NameTable );
foreach ( KeyValuePair<string, string> nskvp in nav.GetNamespacesInScope( XmlNamespaceScope.All ) ) {
nsman.AddNamespace( nskvp.Key, nskvp.Value );
}
XPathNodeIterator nodes;
XPathExpression failingexpr = XPathExpression.Compile( "/src:SRCExample/DataBlock/a:DocID/a:IdID" );
failingexpr.SetContext( nsman );
nodes = nav.Select( failingexpr );
while ( nodes.MoveNext() ) {
string testvalue = nodes.Current.Value;
}
XPath の「DataBlock」要素に絞り込みましたが、DataBlock 要素を単純にワイルドカード化する以外に機能させることはできませんでした。
XPathExpression workingexpr = XPathExpression.Compile( "/src:SRCExample/*/a:DocID/a:IdID" );
failingexpr.SetContext( nsman );
nodes = nav.Select( failingexpr );
while ( nodes.MoveNext() ) {
string testvalue = nodes.Current.Value;
}
多くの頭を悩ませてグーグルで調べた後(ここにたどり着きました)、XmlNamespaceManagerローダーでデフォルトの名前空間を次のように変更して直接取り組むことにしました。
foreach ( KeyValuePair<string, string> nskvp in nav.GetNamespacesInScope( XmlNamespaceScope.All ) ) {
nsman.AddNamespace( nskvp.Key, nskvp.Value );
if ( nskvp.Key == "" ) {
nsman.AddNamespace( "default", nskvp.Value );
}
}
したがって、「デフォルト」と「」は同じ名前空間を指します。これを行うと、XPath "/src:SRCExample/default:DataBlock/a:DocID/a:IdID" が希望どおりの結果を返しました。うまくいけば、これが他の人の問題を明確にするのに役立ちます。