web-dev-qa-db-ja.com

XmlDocument.SelectSingleNodeおよびxmlNamespaceの問題

次の構造を含む文字列をXMLドキュメントにロードしています。

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">                  
  <ItemGroup>
    <Compile Include="clsWorker.cs" />        
  </ItemGroup>      
</Project>

次に、すべてをxmldocumentにロードします。

XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(Xml);

その後、次の問題が発生します。

XmlNode Node = xmldoc.SelectSingleNode("//Compile"); // return null

ルート要素(プロジェクト)からxmlns属性を削除すると、うまく機能しますが、SelectSingleNodeを改善して関連要素を返すにはどうすればよいですか?

43
Shlomi Komemi

SelectSingleNode() への呼び出しで XmlNamespaceManager を使用する必要があります。

XmlNamespaceManager ns = new XmlNamespaceManager(xmldoc.NameTable);
ns.AddNamespace("msbld", "http://schemas.Microsoft.com/developer/msbuild/2003");
XmlNode node = xmldoc.SelectSingleNode("//msbld:Compile", ns);
81

MSDNのSelectSingleNode()のドキュメント


XPath式にプレフィックスが含まれていない場合、名前空間URIは空の名前空間であると見なされます。 XMLにデフォルトのネームスペースが含まれている場合、XmlNamespaceManagerにプレフィックスとネームスペースURIを追加する必要があります。それ以外の場合、ノードは選択されません。詳細については、「 XPathナビゲーションを使用してノードを選択 」を参照してください。

そして、すぐ後に続くサンプルコードは

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ab", "http://www.lucernepublishing.com");
XmlNode book = doc.SelectSingleNode("//ab:book", nsmgr);

それはnotasifthiswould - be " hiddenknowledge "。 ;-)

18
Tomalak

'ItemGroup'には複数の 'Compile'子があり、 'Project/ItemGroup'の 'Compile'子が特に必要なため、以下はすべての望ましい 'Compile'子を返し、その他は返しません。

XmlDocument projectDoc = new XmlDocument();
projectDoc.Load(projectDocPath);
XmlNamespaceManager ns = new XmlNamespaceManager(projectDoc.NameTable);
ns.AddNamespace("msbld", "http://schemas.Microsoft.com/developer/msbuild/2003");
XmlNodeList xnList = projectDoc.SelectNodes(@"/msbld:Project/msbld:ItemGroup/msbld:Compile", ns);

'msbld:'名前空間の指定は、各ノードレベルの前にある必要があることに注意してください。

3
user3902302

この方法では、名前空間を指定する必要はありません。

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml("your xml");
XmlNode node = xmlDoc.SelectSingleNode("/*[local-name() = 'Compile']");
XmlNode nodeToImport = xmlDoc2.ImportNode(node, true);
xmlDoc2.AppendChild(nodeToImport);
2
Bruno B