获取带命名空间的XML节点的最简单方法是什么?

4

我有以下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返回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"。
我做错了什么?

1
这个问题被贬得太过了。对于初学者来说,默认命名空间适用于子元素并不明显。此外,原帖已经提供了必要的 mcve 。我会点赞并且提高编辑时间戳;希望一些严厉的反对意见能够看到并且改变。 - kjhughes
@kjhughes同意。这是一个清晰简洁地陈述问题的声明。 - Charles Mager
我已经习惯了。有些人在SO上毫无理由地四处贬低。可能是那些在厕所墙壁上划脏话的人。SO可以轻松阻止这种行为,方法是使downvotes不匿名,或者至少要求附带下降的原因。 - HerrimanCoder
2个回答

3

命名空间绑定是继承的,因此子元素与其父元素在相同的命名空间中。

您需要将缺失的命名空间前缀添加到查询中:

//anet:messages/anet:message/anet:text

话虽如此,我通常更喜欢使用LINQ to 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();

可以查看此处的fiddle获取一个可运行的演示。


1
你可以使用 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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接