获取具有命名空间的 XML 个节点的最简单方法?
Simplest way to get XML nodes with namespace?
我有以下 XML:
<?xml version="1.0" encoding="UTF-8"?>
<createTransactionResponse xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<messages>
<resultCode>Ok</resultCode>
<message>
<code>I00001</code>
<text>Successful.</text>
</message>
</messages>
<transactionResponse>
<responseCode>1</responseCode>
<authCode>25C10X</authCode>
<messages>
<message>
<code>1</code>
<description>This transaction has been approved.</description>
</message>
</messages>
</transactionResponse>
</createTransactionResponse>
从 createTransactionResponse->messages->message->text
获取值 "Successful." 的最简单方法是什么?
这是我的代码:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("anet", "AnetApi/xml/v1/schema/AnetApiSchema.xsd");
var myNodes = doc.SelectNodes("//anet:messages", nsmgr);
myNodes returns 2 个节点。节点[0]的innerxml是:
<resultCode xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">Ok</resultCode><message xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<code>I00001</code>
<text>Successful.</text>
</message>
节点[1]的innerxml是:
<message xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<code>1</code>
<description>This transaction has been approved.</description>
</message>
我的问题是我不能再深入了。
//anet:messages/message
没有任何结果。
//anet:createTransactionResponse/messages
没有任何结果。
我只是想获取特定的元素值,例如 "I00001" 和“25C10X”。
我做错了什么?
命名空间绑定是继承的,所以这里的子元素与其父元素在同一个命名空间中。
您需要将缺少的命名空间前缀添加到您的查询中:
//anet:messages/anet:message/anet:text
也就是说,我通常更喜欢 LINQ 而不是 XML 而不是 XPath:
XNamespace ns = "AnetApi/xml/v1/schema/AnetApiSchema.xsd";
var root = XElement.Parse(xml);
var text = (string) root.Elements(ns + "messages")
.Descendants(ns + "text")
.Single();
有关工作演示,请参阅 this fiddle。
您也可以使用 LocalName 属性 来避免使用命名空间:
XDocument root = XDocument.Parse(xml);
string text = root.Descendants()
.First(node => node.Name.LocalName == "messages").Elements()
.First(node => node.Name.LocalName == "message").Elements()
.First(node => node.Name.LocalName == "text").Value;
我有以下 XML:
<?xml version="1.0" encoding="UTF-8"?>
<createTransactionResponse xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<messages>
<resultCode>Ok</resultCode>
<message>
<code>I00001</code>
<text>Successful.</text>
</message>
</messages>
<transactionResponse>
<responseCode>1</responseCode>
<authCode>25C10X</authCode>
<messages>
<message>
<code>1</code>
<description>This transaction has been approved.</description>
</message>
</messages>
</transactionResponse>
</createTransactionResponse>
从 createTransactionResponse->messages->message->text
获取值 "Successful." 的最简单方法是什么?
这是我的代码:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("anet", "AnetApi/xml/v1/schema/AnetApiSchema.xsd");
var myNodes = doc.SelectNodes("//anet:messages", nsmgr);
myNodes returns 2 个节点。节点[0]的innerxml是:
<resultCode xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">Ok</resultCode><message xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<code>I00001</code>
<text>Successful.</text>
</message>
节点[1]的innerxml是:
<message xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<code>1</code>
<description>This transaction has been approved.</description>
</message>
我的问题是我不能再深入了。
//anet:messages/message
没有任何结果。
//anet:createTransactionResponse/messages
没有任何结果。
我只是想获取特定的元素值,例如 "I00001" 和“25C10X”。
我做错了什么?
命名空间绑定是继承的,所以这里的子元素与其父元素在同一个命名空间中。
您需要将缺少的命名空间前缀添加到您的查询中:
//anet:messages/anet:message/anet:text
也就是说,我通常更喜欢 LINQ 而不是 XML 而不是 XPath:
XNamespace ns = "AnetApi/xml/v1/schema/AnetApiSchema.xsd";
var root = XElement.Parse(xml);
var text = (string) root.Elements(ns + "messages")
.Descendants(ns + "text")
.Single();
有关工作演示,请参阅 this fiddle。
您也可以使用 LocalName 属性 来避免使用命名空间:
XDocument root = XDocument.Parse(xml);
string text = root.Descendants()
.First(node => node.Name.LocalName == "messages").Elements()
.First(node => node.Name.LocalName == "message").Elements()
.First(node => node.Name.LocalName == "text").Value;