使用XPath选择/过滤XML元素

时间:2013-01-30 22:01:25

标签: php dom xpath namespaces xml-namespaces

这是我的amazon mws api responce

<?xml version="1.0"?>
<GetMyPriceForSKUResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetMyPriceForSKUResult SellerSKU="ds-tru-6sss" 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>Assssssss</MarketplaceId>
        <ASIN>sss</ASIN>
      </MarketplaceASIN>
      <SKUIdentifier>
        <MarketplaceId>Afasrfd</MarketplaceId>
        <SellerId>ssssss</SellerId>
        <SellerSKU>dssss</SellerSKU>
      </SKUIdentifier>
    </Identifiers>
    <Offers>
      <Offer>
        <BuyingPrice>
          <LandedPrice>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>12.49</Amount>
          </LandedPrice>
          <ListingPrice>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>12.49</Amount>
          </ListingPrice>
          <Shipping>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>0.00</Amount>
          </Shipping>
        </BuyingPrice>
        <RegularPrice>
          <CurrencyCode>USD</CurrencyCode>
          <Amount>12.49</Amount>
        </RegularPrice>
        <FulfillmentChannel>MERCHANT</FulfillmentChannel>
        <ItemCondition>New</ItemCondition>
        <ItemSubCondition>New</ItemSubCondition>
        <SellerId>Aadada</SellerId>
        <SellerSKU>ssss</SellerSKU>
      </Offer>
      <Offer>
        <BuyingPrice>
          <LandedPrice>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>1000.00</Amount>
          </LandedPrice>
          <ListingPrice>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>1000.00</Amount>
          </ListingPrice>
          <Shipping>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>0.00</Amount>
          </Shipping>
        </BuyingPrice>
        <RegularPrice>
          <CurrencyCode>USD</CurrencyCode>
          <Amount>1000.00</Amount>
        </RegularPrice>
        <FulfillmentChannel>MERCHANT</FulfillmentChannel>
        <ItemCondition>New</ItemCondition>
        <ItemSubCondition>New</ItemSubCondition>
        <SellerId>ssss</SellerId>
        <SellerSKU>sss</SellerSKU>
      </Offer>
    </Offers>
  </Product>
</GetMyPriceForSKUResult>
<ResponseMetadata>
  <RequestId>e0ef1c2c-4f35-4316-8629-faadadd</RequestId>
</ResponseMetadata>
</GetMyPriceForSKUResponse>

并从

中选择amount (12.49)
<ListingPrice>
    <CurrencyCode>USD</CurrencyCode>
    <Amount>12.49</Amount>
</ListingPrice>

我在努力,

// from curl
$result = curl_exec ($ch);
$xmldoc = new DOMDocument();
$xmldoc->load($result);
$xpathvar = new Domxpath($xmldoc);

$queryResult = $xpathvar->query('/Amount');
foreach($queryResult as $result){
    echo $result;
}

我期待这个价值超过一个值,但我根本没有。

抱歉,我不擅长XPath,有人可以指导我吗?

3 个答案:

答案 0 :(得分:2)

目前我在您的代码中发现了错误:


首先:使用两个//来选择一个元素,无论它在xml树中的位置如何。

 $queryResult = $xpathvar->query('//Amount');

第二:谢谢@Ranon。您将负责文档xml命名空间:

// Register Namespace mws
$xpathvar->registerNamespace("mws", 'http://mws.amazonservices.com/schema/Products/2011-10-01');

...并使用它,意思是:

 $queryResult = $xpathvar->query('//mws:Amount');

第三:如果要选择文本节点(在<amount>节点之间),您应该使用:

$queryResult = $xpathvar->query('//mws:Amount/text()');

否则,您可以选择父元素<Amount>(正如您已经做过的那样)并使用PHP检索值。然后你必须将你的代码更改为:

$queryResult = $xpathvar->query('//mws:Amount');
foreach($queryResult as $result){
   echo $result->nodeValue; // echo the node value, not the node 'itself'
}

第四:还要注意代码中的另一个错误。从xml字符串创建DOMDocument时,您必须使用:

$document->loadXML($result);

第五:您告诉您要在<Amount>元素中检索<ListingPrice>元素表单。请注意,<Amount>元素中还有<RegularPrice>个元素。因此确实重要 <Amount>元素位于树中。使用以下查询仅获取列表价格金额:

$queryResult = $xpathvar->query('//mws:ListingPrice/mws:Amount');

答案 1 :(得分:2)

Amazon使用您必须声明和使用的命名空间返回XML。

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// from curl
$result = curl_exec($ch);
$xmldoc = new DOMDocument();
$xmldoc->loadXML($result);
$xpathvar = new Domxpath($xmldoc);
// Register Namespace mws
$xpathvar->registerNamespace("mws", 'http://mws.amazonservices.com/schema/Products/2011-10-01');

// Query using namespace mws
$queryResult = $xpathvar->query('//mws:Amount');
foreach($queryResult as $result){
    echo $result->nodeValue;
}

我从子域中任意选择了命名空间标识符mws,如果需要,可以选择另一个。

我更正了@ hek2mgl找到的代码中的其他一些错误。

答案 2 :(得分:0)

XPath表达式错误。您需要'//Amount'来选择所有“金额”元素