2015-12-17 131 views
0

下面是一個示例XML我試圖解析的一部分:「的SelectSingleNode」從XML XPath查詢與多個命名空間

<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 

我努力的目標和檢索/價格文/ LandedPrice /數量/節點(在這種情況下爲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中返回錯誤代碼:

'Object variable or With block reference not set'.

調試代碼表明的SelectSingleNode正在返回什麼。我對命名空間前綴的理解以及它如何適用於XPath非常有限。我可以通過名稱空間找到很多XML示例,但是,有多個名稱空間的示例非常有限。

+0

您嘗試獲得的元素在命名空間'的xmlns =「http://mws.amazonservices.com/schema/Products/2011-10-01」 '。從你的屬性「SelectionNamespaces」這是'ns1'而不是'ns2'。 –

+0

是啊,就像axel說你錯過了你的第一個命名空間,你可以跳過上面的元素,以'// //'開頭。 '// ns2:Product' –

+0

另外元素'Product'不在命名空間'ns2'中。在發佈的'XML'代碼中,這個名稱空間中沒有任何元素。 –

回答

0

因爲在根標記中有一個默認名稱空間,所以只需要聲明一個名稱空間而不是多個。考慮以下調整去除其他聲明:

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 
+0

完美的作品!感謝詳細的解釋,這已經從我這裏解釋了很多。 – stokebob