2016-03-02 1 views
0

У меня есть XML, который иногда имеет конкретный контент, который присутствует, и в другое время его нет в XML. Когда этих данных нет, это приводит к тому, что моя процедура разбора VBA имеет значение barf. Поэтому мне нужно проверить конкретный путь, чтобы увидеть, существует ли он до попытки захвата данных.XML, как установить, существует ли узел в VBA перед использованием команды Xpath на нем

Dim objxmldoc As New MSXML2.DOMDocument60 

XMLHttpRequest.Open "GET", SignedURL, False 

XMLHttpRequest.send (SignedURL) 

objxmldoc.loadXML (XMLHttpRequest.responseXML.XML) 

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 NoOfASINs = objxmldoc.selectNodes("//ns1:GetCompetitivePricingForASINResult") 

i = 0 
For Each n In NoOfASINs 
    Set objxmlASIN = objxmldoc.selectNodes("/ns1:ASIN") 
    Set objXMLPrice = objxmldoc.selectNodes("/ns1:Product/ns1:CompetitivePricing/ns1:CompetitivePrices/ns1:CompetitivePrice") 

    Debug.Print objxmlASIN(i).text + "," + objXMLPrice(i).text 
    i = i + 1 
Next 

Иногда нет ничего под /ns1:Product/ns1:CompetitivePricing/ns1:CompetitivePrices ... так что мне нужно проверить в первую очередь.

<GetCompetitivePricingForASINResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01"> 
     <GetCompetitivePricingForASINResult ASIN="B002NJHGN6" 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>B002NJHGN6</ASIN> 
           </MarketplaceASIN> 
         </Identifiers> 
        <CompetitivePricing> 
          <CompetitivePrices> 
            <CompetitivePrice belongsToRequester="true" condition="New" subcondition="New"> 
              <CompetitivePriceId>1</CompetitivePriceId> 
              <Price> 
               <LandedPrice> 
                 <CurrencyCode>GBP</CurrencyCode> 
                 <Amount>17.69</Amount> 
                </LandedPrice> 
               <ListingPrice> 
                 <CurrencyCode>GBP</CurrencyCode> 
                 <Amount>17.69</Amount> 
                </ListingPrice> 
               <Shipping> 
                 <CurrencyCode>GBP</CurrencyCode> 
                 <Amount>0.00</Amount> 
                </Shipping> 
              </Price> 
             </CompetitivePrice> 
           </CompetitivePrices> 
          <NumberOfOfferListings> 
            <OfferListingCount condition="New">16</OfferListingCount> 
            <OfferListingCount condition="Any">16</OfferListingCount> 
           </NumberOfOfferListings> 
         </CompetitivePricing> 
        <SalesRankings> 
          <SalesRank> 
            <ProductCategoryId>home_improvement_display_on_website</ProductCategoryId> 
            <Rank>10299</Rank> 
           </SalesRank> 
          <SalesRank> 
            <ProductCategoryId>home_and_garden_display_on_website</ProductCategoryId> 
            <Rank>51823</Rank> 
           </SalesRank> 
          <SalesRank> 
            <ProductCategoryId>1939047031</ProductCategoryId> 
            <Rank>28</Rank> 
           </SalesRank> 
         </SalesRankings> 
       </Product> 
      </GetCompetitivePricingForASINResult> 
     <GetCompetitivePricingForASINResult ASIN="B003F9MNF4" 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>B003F9MNF4</ASIN> 
           </MarketplaceASIN> 
         </Identifiers> 
        <CompetitivePricing> 
          <CompetitivePrices></CompetitivePrices> 
          <NumberOfOfferListings> 
            <OfferListingCount condition="New">2</OfferListingCount> 
            <OfferListingCount condition="Any">2</OfferListingCount> 
           </NumberOfOfferListings> 
         </CompetitivePricing> 
        <SalesRankings> 
          <SalesRank> 
            <ProductCategoryId>home_improvement_display_on_website</ProductCategoryId> 
            <Rank>141917</Rank> 
           </SalesRank> 
          <SalesRank> 
            <ProductCategoryId>home_and_garden_display_on_website</ProductCategoryId> 
            <Rank>892073</Rank> 
           </SalesRank> 
          <SalesRank> 
            <ProductCategoryId>1939038031</ProductCategoryId> 
            <Rank>868</Rank> 
           </SalesRank> 
         </SalesRankings> 
       </Product> 
      </GetCompetitivePricingForASINResult> 
     <GetCompetitivePricingForASINResult ASIN="B002F9nNFY" 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>B002F9nNFY</ASIN> 
           </MarketplaceASIN> 
         </Identifiers> 
        <CompetitivePricing> 
          <CompetitivePrices> 
            <CompetitivePrice belongsToRequester="true" condition="New" subcondition="New"> 
              <CompetitivePriceId>1</CompetitivePriceId> 
              <Price> 
               <LandedPrice> 
                 <CurrencyCode>GBP</CurrencyCode> 
                 <Amount>113.99</Amount> 
                </LandedPrice> 
               <ListingPrice> 
                 <CurrencyCode>GBP</CurrencyCode> 
                 <Amount>113.99</Amount> 
                </ListingPrice> 
               <Shipping> 
                 <CurrencyCode>GBP</CurrencyCode> 
                 <Amount>0.00</Amount> 
                </Shipping> 
              </Price> 
             </CompetitivePrice> 
           </CompetitivePrices> 
          <NumberOfOfferListings> 
            <OfferListingCount condition="New">2</OfferListingCount> 
            <OfferListingCount condition="Any">2</OfferListingCount> 
           </NumberOfOfferListings> 
         </CompetitivePricing> 
        <SalesRankings> 
          <SalesRank> 
            <ProductCategoryId>home_improvement_display_on_website</ProductCategoryId> 
            <Rank>170655</Rank> 
           </SalesRank> 
          <SalesRank> 
            <ProductCategoryId>home_and_garden_display_on_website</ProductCategoryId> 
            <Rank>1098520</Rank> 
           </SalesRank> 
          <SalesRank> 
            <ProductCategoryId>1939038031</ProductCategoryId> 
            <Rank>1031</Rank> 
           </SalesRank> 
         </SalesRankings> 
       </Product> 
      </GetCompetitivePricingForASINResult> 
     <ResponseMetadata> 
       <RequestId>efa320b7-0162-49fc-a328-2f8d93f55f2f</RequestId> 
      </ResponseMetadata> 
    </GetCompetitivePricingForASINResponse> 
+0

«XML-ниже вызывает много душевной боли» - как так? Вы должны быть в состоянии проверить, возвращает ли ваш запрос Xpath хит или нет. Помогло бы вашему вопросу a включить код, который вы используете. –

+0

Хорошо, я добавил код - надеюсь, будет более ясно, что я хочу «проверить», чтобы увидеть, существует ли путь первым. – peskywinnets

+0

'SelectNodes' возвращает пустую коллекцию, если не было найдено никаких хитов, поэтому проверьте, что' objxmlASIN.Length' не равен нулю, прежде чем пытаться получить доступ к любому из содержимого. –

ответ

0
  1. У вас есть For Each петли, что происходит с этим индексом счетчиком?
  2. Использовать относительные XPaths (начиная с ./).
  3. Используйте SelectSingleNode если вы ожидаете только одного результата.
  4. Не используйте объекты, которые могут быть установлены на Nothing.

Лучше:

Set PricingResults = doc.SelectNodes("//ns1:GetCompetitivePricingForASINResult") 

For Each Result In PricingResults 
    Set ASIN = Result.SelectSingleNode(".//ns1:ASIN") 
    Set Price = Result.SelectSingleNode(".//ns1:CompetitivePrice") 

    If Not ASIN Is Nothing And Not Price Is Nothing Then 
     Debug.Print ASIN.text + "," + Price.text 
    End If 
Next 

В несвязанной ноте я бы рекомендовал отказаться от венгерской нотации. Настолько много печатей и никакой реальной выгоды.

+0

Привет, Томалак, спасибо за ваш вклад ... как вы наверняка собрались, я относительно новичок в кодировании ..... Я приветствую возможность улучшить код, который я использую. Тем не менее, я получаю ошибку компиляции (синтаксическую ошибку) с ** Если не ASIN ничего, а не цена, это ничего ..... ..... ваше использование «не» и «ничего» в коде ... Вы можете уточнить, что там происходит ?! – peskywinnets

+0

'SelectSingleNode' возвращает' Nothing', если он не находит совпадения, тогда как 'selectNodes' возвращает * пустую коллекцию * (не' Nothing') –

+1

Спасибо ... это выглядит интересно, я отсортировал ошибку компиляции (ему не хватало «тогда» .... отключить, чтобы иметь dabble :-) – peskywinnets

0

SelectNodes возвращение пустой коллекции, если не было найдено ни одного попадания, поэтому проверить, что objxmlASIN.Length не равен нулю, прежде чем пытаться получить доступ к любому из содержания

If objxmlASIN.Length >0 Then 
    Debug.print "OK" 
Else 
    Debug.print "No Match!" 
End If 
+0

cool .... спасибо (наконец, я теперь знаю, как это использовать!) – peskywinnets

+0

Я получаю несоответствие типа ... что должно быть объявлено objxmlASIN при использовании суффикса **. Length ** (в настоящее время у меня есть это как ** Dim objxmlASIN As MSXML2.IXMLDOMNodeList **) – peskywinnets

+0

Я бы пошел с @Tomalak на этом ... –