使用XPath选择/过滤XML元素
here is my 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>
and to select amount (12.49)
from
<ListingPrice>
<CurrencyCode>USD</CurrencyCode>
<Amount>12.49</Amount>
</ListingPrice>
I am trying ,
// 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;
}
I am expecting more then one value for this, but I am getting none at all.
Sorry, I am not good at XPath, can somebody guide me?
Currently I found errors in your code:
First: Use two //
to select an element regardless of where it is located in the xml tree.
$queryResult = $xpathvar->query('//Amount');
Second: thanks @Ranon. You'll take care of the documents xml namespace:
// Register Namespace mws
$xpathvar->registerNamespace("mws", 'http://mws.amazonservices.com/schema/Products/2011-10-01');
... and use it, means:
$queryResult = $xpathvar->query('//mws:Amount');
Third: If you want to select the text node (between the <amount>
nodes) you should use:
$queryResult = $xpathvar->query('//mws:Amount/text()');
Otherwise you can select the parent element <Amount>
(as you already doing) and retrieve the value with PHP. Then you have to change your code to:
$queryResult = $xpathvar->query('//mws:Amount');
foreach($queryResult as $result){
echo $result->nodeValue; // echo the node value, not the node 'itself'
}
Fourth: Also note another error in your code. When you create a DOMDocument from an xml string you'll have to use:
$document->loadXML($result);
Fifth: You told that you want to retrieve the <Amount>
elements form inside <ListingPrice>
elements. Note that there are also <Amount>
elements inside <RegularPrice>
elements. So it does matter where the <Amount>
element is located in tree. Use the following query to obtain only listing price amounts:
$queryResult = $xpathvar->query('//mws:ListingPrice/mws:Amount');
The XPath expression is wrong. You need '//Amount'
to select all the "Amount" elements
Amazon returns XML using a namespace which you have to declare and use.
$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;
}
I selected the namespace identifier mws
arbitrarily from the subdomain, you can choose another if you want.
I corrected some other errors in the code found by @hek2mgl.