'的SelectSingleNode'来自具有多个命名空间的XML的XPath查询

时间:2015-12-17 13:36:09

标签: xml excel vba excel-vba xpath

这是我试图解析的示例XML的一部分:

<GetCompetitivePricingForASINResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
    <GetCompetitivePricingForASINResult ASIN="B014P3CM08" status="Success">
        <Product xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01" xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd">
            <Identifiers>
                <MarketplaceASIN>
                    <MarketplaceId>A1F83G8C2ARO7P</MarketplaceId>
                    <ASIN>B014P3CM08</ASIN>
                </MarketplaceASIN>
            </Identifiers>
            <CompetitivePricing>
                <CompetitivePrices>
                    <CompetitivePrice belongsToRequester="false" condition="New" subcondition="New">
                        <CompetitivePriceId>1</CompetitivePriceId>
                            <Price>
                                <LandedPrice>
                                    <CurrencyCode>GBP</CurrencyCode>
                                    <Amount>24.00</Amount>
                                </LandedPrice>
                                <ListingPrice>
                                    <CurrencyCode>GBP</CurrencyCode>
                                    <Amount>24.00</Amount>
                                </ListingPrice>
                                <Shipping>
                                    <CurrencyCode>GBP</CurrencyCode>
                                    <Amount>0.00</Amount>
                                </Shipping>
                            </Price>
                        </CompetitivePrice>
                    </CompetitivePrices>
.... etc

我正在尝试从/ Price / LandedPrice / Amount /节点(在这种情况下为24.00)中定位和检索文本。这是我到目前为止的VBA代码:

Dim strXMLSite As String
Dim objXMLHTTP As MSXML2.XMLHTTP60
Dim objXMLDoc As MSXML2.DOMDocument60
Dim objXMLNode1 As MSXML2.IXMLDOMNode

Set objXMLHTTP = New MSXML2.XMLHTTP60
Set objXMLDoc = New MSXML2.DOMDocument60

Call MWSProductAPI

strXMLSite = Worksheets("Settings").Range("B12").Value

objXMLHTTP.Open "GET", strXMLSite, False
objXMLHTTP.send
objXMLDoc.LoadXML (objXMLHTTP.responseText)

XmlNamespaces = "xmlns:ns2='http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd' xmlns:ns1='http://mws.amazonservices.com/schema/Products/2011-10-01'"

objXMLDoc.setProperty "SelectionNamespaces", XmlNamespaces

Set objXMLNode1 = objXMLDoc.SelectSingleNode("/ns2:GetCompetitivePricingForASINResponse/ns2:GetCompetitivePricingForASINResult/ns2:Product/ns2:CompetitivePricing/ns2:CompetitivePrices/ns2:CompetitivePrice/ns2:Price/ns2:LandedPrice/ns2:Amount")
Worksheets("Settings").Range("C8").Value = objXMLNode1.text

但是,当我在Excel中运行代码时,它会返回错误:

  

&#39;对象变量或使用块参考未设置&#39;。

调试代码显示SelectSingleNode没有返回任何内容。我对命名空间前缀的理解以及它如何适应XPath是非常有限的。我可以找到大量带有命名空间的XML示例,但是,有多个命名空间的示例非常有限。

1 个答案:

答案 0 :(得分:1)

因为在root标记中有一个默认命名空间,所以只需声明一个命名空间,而不是多个命名空间。在删除其他声明时请考虑以下调整:

XmlNamespaces = "xmlns:ns2='http://mws.amazonservices.com/schema/Products/2011-10-01'"

objXMLDoc.setProperty "SelectionNamespaces", XmlNamespaces

Set objXMLNode1 = objXMLDoc.SelectSingleNode("/ns2:GetCompetitivePricingForASINResponse" _
                            & "/ns2:GetCompetitivePricingForASINResult/ns2:Product" _
                            & "/ns2:CompetitivePricing/ns2:CompetitivePrices" _
                            & "/ns2:CompetitivePrice/ns2:Price/ns2:LandedPrice/ns2:Amount")

顺便说一句,你可以缩短XPath表达式:

Set objXMLNode1 = objXMLDoc.SelectSingleNode("//ns2:Price/ns2:LandedPrice/ns2:Amount")

即使使用列表,如果出现多个LandedPrice(但将声明更改为节点列表并使用索引表示法作为返回值):

...
Dim objXMLNode1 As MSXML2.IXMLDOMNodeList
...

Set objXMLNode1 = objXMLDoc.DocumentElement.SelectNodes(" _
                       & //ns2:Price/ns2:LandedPrice/ns2:Amount")

Worksheets("Settings").Range("C8").Value = objXMLNode1(0).Text