XDocumentという便利なXML操作用のクラスがあります。このクラスは通常ではXPathによる検索、解析用の機能はありません。
ところが、System.Xml.XPath
をusingするとXPath用の拡張メソッドが使えます。とても便利です。これでXPathで楽に要素の取得ができます。
//XDocumentでXPath用の拡張メソッドを使うのに必要
using System.Xml.XPath;
しかし、XMLが名前空間付きの場合、面倒な問題があります。いちいち名前空間(namespace)を指定しないといけないのです。
名前空間を指定する場合
//XML文字列からXDocumentオブジェクトを生成
var doc = XDocument.Load(new StringReader(xmlString));
//名前空間のための処理
string nameSpace = "http://example.com";
var nsmgr = new XmlNamespaceManager(new NameTable());
nsmgr.AddNamespace("ns", nameSpace);
//名前空間を指定して検索
var nodeD = doc.XPathSelectElement("ns:nodeA/ns:nodeB/ns:nodeC/ns:nodeD", nsmgr);
XmlNamespaceManagerを作り、XPathSelectElementを呼び出す度にこれを渡さないといけません。それだけならまだいいのですが、XPathの指定で毎回ns:を付けるのが非常に面倒だし可読性も悪いです。
名前空間を無視して検索する
以上のように名前空間を指定すると色々面倒です。
この問題の解決策として、名前空間を無視して解析する方法が以下です。
//XML文字列からXDocumentオブジェクトを生成
var doc = XDocument.Load(new StringReader(xmlString));
//各ノードのNameを名前空間なしの要素名にする
foreach(var e in doc.Descendants()) e.Name = e.Name.LocalName;
//上記処理により、検索時に名前空間の指定が不要
var nodeD = doc.XPathSelectElement("nodeA/nodeB/nodeC/nodeD");
無理矢理な感じですが、動いているので多分大丈夫でしょう。
これですっきり!