【问题标题】:Parsing Amzon API *.xml response [duplicate]解析 Amzon API *.xml 响应 [重复]
【发布时间】:2015-03-02 03:54:18
【问题描述】:

我正在尝试解析来自 amazon api 的 xml 响应。

这是收到的 xml 文件的一部分:

<BrowseNodeLookupResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
  <OperationRequest>
    <RequestId>31317fca-ad3d-4ff0-a64f-693c0e44959b</RequestId>
    <Arguments>
      <Argument Name="Operation" Value="BrowseNodeLookup" />
      <Argument Name="Service" Value="AWSECommerceService" />
      <Argument Name="Version" Value="2011-08-01" />
      <Argument Name="BrowseNodeId" Value="186606" />
      <Argument Name="Timestamp" Value="2015-01-04T11:50:06Z" />
      <Argument Name="ResponseGroup" Value="BrowseNodeInfo" />
    </Arguments>
    <RequestProcessingTime>0.002221</RequestProcessingTime>
  </OperationRequest>
  <BrowseNodes>

我想阅读参数时间戳。这是我的代码,但它只有在我删除 xml 文件中的 xmlns 属性时才有效。

    Dim nodeTimestamp As XmlNode = doc.SelectSingleNode("/BrowseNodeLookupResponse/OperationRequest/Arguments/Argument[@Name='Timestamp']")

    Dim text As String = nodeTimestamp.Attributes.ItemOf("Value").InnerText

【问题讨论】:

  • 这是一个非常常见的问题。答案是使用XmlNamespaceManager 并为该亚马逊命名空间声明一个前缀。

标签: .net xml vb.net parsing amazon


【解决方案1】:

我假设你从亚马逊收到一个有效的 XML(最后一个结束标签是&lt;/BrowseNodeLookupResponse&gt;。你可以使用LINQ2XML 来选择所需值属性的值。你需要采用默认命名空间并使用它在访问和搜索 XML 中的特定元素/节点时。例如,我将您的 XML 输入保存在一个名为 axml.xml 的文件中:

' load the xml. Use XDocument.Parse to load a XML-Structure from a String!
Dim xml as XDocument = XDocument.Load("c:\temp\axml.xml")
' get the namespace for later use
Dim ns = xml.Root.GetDefaultNamespace()
' find the Arguments node, holding all Argument nodes. Note the use of the namespace
Dim arguments = xml.Root _
    .Descendants(ns + "Arguments") _ 
    .Elements(ns + "Argument")
' find and take the Argument node with the specified name
Dim ts = from argument in arguments
         where argument.Attribute("Name").Value = "Timestamp"
         select argument
' take the value of the desired attribute
Console.WriteLine(ts.FirstOrDefault().Attribute("Value").Value)

输出是:

2015-01-04T11:50:06Z

如果您想坚持使用 XmlDocument 方法,则需要使用 XmlDocumentNamespaceManager (as shown in this SO post) 才能使用命名空间检索节点。解决方案可能如下所示:

Dim xml = new XmlDocument()
xml.Load("c:\temp\axml.xml")
Dim xmlnsManager = new XmlNamespaceManager(xml.NameTable)
' take the custom namespace and add it to the namespace manager
xmlnsManager.AddNamespace("custom", xml.ChildNodes(0).Attributes("xmlns").Value)
' find the desired node
Dim nodeTimestamp = xml.SelectSingleNode("//custom:Arguments/custom:Argument[@Name='Timestamp']", xmlnsManager)
' and take the attribute value
Console.WriteLine(nodeTimestamp.Attributes("Value").Value)

输出同上。

【讨论】:

  • 感谢您的回答。我将尝试使用 Linq to,因为我也将它用于我项目中的其他事情。我想知道命名空间管理器的意义是什么,因为我在亚马逊上看到了演示代码。现在我知道,有了命名空间管理器,我的代码就可以工作了。
  • 我添加了一个使用 XmlDocument 的解决方案,如您的示例所示。
  • @Tomalak 谢谢你的评论——你说得对,我已经删除了PushScope。关于空前缀 - 它不起作用。
  • 你说得对,它需要一个前缀。我误解了。另一方面,我认为盲目地从 XML 文档本身中获取默认的 xmlns 值是一个错误。 XML 命名空间是合同的一部分,它们应该是硬编码的。我会这样做:pastebin.com/ELyPeEtW
  • @Tomalak 你对硬编码前缀是正确的,我只是想减少复制/粘贴。你的解决方案比我的更优雅、更简单。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多