анализировать XML-ответ с пространствами имен

Я отправляю запрос на получение информации о продукте в Amazon и получаю от них ответ в формате XML — это выглядит так:

<?xml version="1.0"?>
<GetMatchingProductForIdResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<GetMatchingProductForIdResult Id="3U-R7EP-QODZ" IdType="SellerSKU" status="Success">
<Products>
<Product>
<Identifiers>
<MarketplaceASIN>
<MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
<ASIN>B0002DV7Z2</ASIN>
</MarketplaceASIN>
</Identifiers>
<AttributeSets>
<ns2:ItemAttributes xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd" xml:lang="en-US">
<ns2:Binding>Electronics</ns2:Binding>
<ns2:Brand>Pioneer</ns2:Brand>
<ns2:Color>Black</ns2:Color>
<ns2:Feature>Whether a DJ, studio musician, sound engineer or just an avid music listener, the HDJ-1000 is the answer to all of your headphone needs.</ns2:Feature>
<ns2:Feature>Large diameter speaker units.</ns2:Feature>
<ns2:Feature>Folding housing with universal joints.</ns2:Feature>
<ns2:Feature>Stereo/Mono selector switch allows mix of left and right channel signals for single ear monitoring.</ns2:Feature>
<ns2:Feature>Removable 1/4" jack reveals mini plug for flexible connections, includes carrying case.</ns2:Feature>
<ns2:ItemDimensions>
<ns2:Height Units="inches">11.50</ns2:Height>
<ns2:Length Units="inches">13.00</ns2:Length>
<ns2:Width Units="inches">12.60</ns2:Width>
<ns2:Weight Units="pounds">0.60</ns2:Weight>
</ns2:ItemDimensions>
<ns2:IsAutographed>false</ns2:IsAutographed>
<ns2:IsMemorabilia>false</ns2:IsMemorabilia>
<ns2:Label>Pioneer Pro DJ</ns2:Label>
<ns2:ListPrice>
<ns2:Amount>200.00</ns2:Amount>
<ns2:CurrencyCode>USD</ns2:CurrencyCode>
</ns2:ListPrice>
<ns2:Manufacturer>Pioneer Pro DJ</ns2:Manufacturer>
<ns2:Model>HDJ-1000</ns2:Model>
<ns2:NumberOfItems>1</ns2:NumberOfItems>
<ns2:PackageDimensions>
<ns2:Height Units="inches">4.20</ns2:Height>
<ns2:Length Units="inches">10.00</ns2:Length>
<ns2:Width Units="inches">9.50</ns2:Width>
<ns2:Weight Units="pounds">1.30</ns2:Weight>
</ns2:PackageDimensions>
<ns2:PackageQuantity>1</ns2:PackageQuantity>
<ns2:PartNumber>HDJ-1000</ns2:PartNumber>
<ns2:ProductGroup>Musical Instruments</ns2:ProductGroup>
<ns2:ProductTypeName>SOUND_AND_RECORDING_EQUIPMENT</ns2:ProductTypeName>
<ns2:ProductTypeSubcategory>26705100</ns2:ProductTypeSubcategory>
<ns2:Publisher>Pioneer Pro DJ</ns2:Publisher>
<ns2:ReleaseDate>2008-12-08</ns2:ReleaseDate>
<ns2:SmallImage>
<ns2:URL>http://ecx.images-amazon.com/images/I/31I5ac8P-wL._SL75_.jpg</ns2:URL>
<ns2:Height Units="pixels">75</ns2:Height>
<ns2:Width Units="pixels">75</ns2:Width>
</ns2:SmallImage>
<ns2:Studio>Pioneer Pro DJ</ns2:Studio>
<ns2:Title>Pioneer HDJ-1000 DJ Headphones</ns2:Title>
<ns2:Warranty>1 Year Exchange</ns2:Warranty>
</ns2:ItemAttributes>
</AttributeSets>
<Relationships>
<VariationParent xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
<Identifiers>
<MarketplaceASIN>
<MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
<ASIN>B0074L8U64</ASIN>
</MarketplaceASIN>
</Identifiers>
</VariationParent>
</Relationships>
<SalesRankings>
<SalesRank>
<ProductCategoryId>musical_instruments_display_on_website</ProductCategoryId>
<Rank>28094</Rank>
</SalesRank>
</SalesRankings>
</Product>
</Products>
</GetMatchingProductForIdResult>
<GetMatchingProductForIdResult Id="86-CK3P-PHK6" IdType="SellerSKU" status="Success">
<Products>
<Product>
<Identifiers>
<MarketplaceASIN>
<MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
<ASIN>0061785679</ASIN>
</MarketplaceASIN>
</Identifiers>
<AttributeSets>
<ns2:ItemAttributes xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd" xml:lang="en-US">
<ns2:Author>Rollins, James</ns2:Author>
<ns2:Binding>Mass Market Paperback</ns2:Binding>
<ns2:Brand>Harper</ns2:Brand>
<ns2:Edition>Reprint</ns2:Edition>
<ns2:Feature>Great product!</ns2:Feature>
<ns2:ItemDimensions>
<ns2:Height Units="inches">1.90</ns2:Height>
<ns2:Length Units="inches">7.20</ns2:Length>
<ns2:Width Units="inches">4.20</ns2:Width>
<ns2:Weight Units="pounds">0.70</ns2:Weight>
</ns2:ItemDimensions>
<ns2:Label>Harper</ns2:Label>
<ns2:Languages>
<ns2:Language>
<ns2:Name>english</ns2:Name>
<ns2:Type>Unknown</ns2:Type>
</ns2:Language>
<ns2:Language>
<ns2:Name>english</ns2:Name>
<ns2:Type>Original Language</ns2:Type>
</ns2:Language>
<ns2:Language>
<ns2:Name>english</ns2:Name>
<ns2:Type>Published</ns2:Type>
</ns2:Language>
</ns2:Languages>
<ns2:ListPrice>
<ns2:Amount>9.99</ns2:Amount>
<ns2:CurrencyCode>USD</ns2:CurrencyCode>
</ns2:ListPrice>
<ns2:Manufacturer>Harper</ns2:Manufacturer>
<ns2:NumberOfItems>1</ns2:NumberOfItems>
<ns2:NumberOfPages>576</ns2:NumberOfPages>
<ns2:PackageDimensions>
<ns2:Height Units="inches">1.70</ns2:Height>
<ns2:Length Units="inches">7.40</ns2:Length>
<ns2:Width Units="inches">4.10</ns2:Width>
<ns2:Weight Units="pounds">0.70</ns2:Weight>
</ns2:PackageDimensions>
<ns2:ProductGroup>Book</ns2:ProductGroup>
<ns2:ProductTypeName>ABIS_BOOK</ns2:ProductTypeName>
<ns2:PublicationDate>2014-01-28</ns2:PublicationDate>
<ns2:Publisher>Harper</ns2:Publisher>
<ns2:ReleaseDate>2014-01-28</ns2:ReleaseDate>
<ns2:SmallImage>
<ns2:URL>http://ecx.images-amazon.com/images/I/51evv9CZCOL._SL75_.jpg</ns2:URL>
<ns2:Height Units="pixels">75</ns2:Height>
<ns2:Width Units="pixels">42</ns2:Width>
</ns2:SmallImage>
<ns2:Studio>Harper</ns2:Studio>
<ns2:Title>The Eye of God (Sigma Force)</ns2:Title>
</ns2:ItemAttributes>
</AttributeSets>
<Relationships/>
<SalesRankings>
<SalesRank>
<ProductCategoryId>book_display_on_website</ProductCategoryId>
<Rank>10083</Rank>
</SalesRank>
</SalesRankings>
</Product>
</Products>
</GetMatchingProductForIdResult>
<GetMatchingProductForIdResult Id="NX-USS1-UXRY" IdType="SellerSKU" status="Success">
<Products>
<Product>
<Identifiers>
<MarketplaceASIN>
<MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
<ASIN>0375705244</ASIN>
</MarketplaceASIN>
</Identifiers>
<AttributeSets>
<ns2:ItemAttributes xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd" xml:lang="en-US">
<ns2:Author>Ellis, Joseph J.</ns2:Author>
<ns2:Binding>Paperback</ns2:Binding>
<ns2:Brand>Vintage</ns2:Brand>
<ns2:Feature>Great product!</ns2:Feature>
<ns2:ItemDimensions>
<ns2:Height Units="inches">0.65</ns2:Height>
<ns2:Length Units="inches">7.84</ns2:Length>
<ns2:Width Units="inches">5.48</ns2:Width>
<ns2:Weight Units="pounds">0.51</ns2:Weight>
</ns2:ItemDimensions>
<ns2:Label>Vintage</ns2:Label>
<ns2:Languages>
<ns2:Language>
<ns2:Name>english</ns2:Name>
<ns2:Type>Unknown</ns2:Type>
</ns2:Language>
<ns2:Language>
<ns2:Name>english</ns2:Name>
<ns2:Type>Original Language</ns2:Type>
</ns2:Language>
<ns2:Language>
<ns2:Name>english</ns2:Name>
<ns2:Type>Published</ns2:Type>
</ns2:Language>
</ns2:Languages>
<ns2:ListPrice>
<ns2:Amount>15.95</ns2:Amount>
<ns2:CurrencyCode>USD</ns2:CurrencyCode>
</ns2:ListPrice>
<ns2:Manufacturer>Vintage</ns2:Manufacturer>
<ns2:NumberOfItems>1</ns2:NumberOfItems>
<ns2:NumberOfPages>304</ns2:NumberOfPages>
<ns2:PackageDimensions>
<ns2:Height Units="inches">1.10</ns2:Height>
<ns2:Length Units="inches">7.70</ns2:Length>
<ns2:Width Units="inches">5.10</ns2:Width>
<ns2:Weight Units="pounds">0.50</ns2:Weight>
</ns2:PackageDimensions>
<ns2:PackageQuantity>1</ns2:PackageQuantity>
<ns2:PartNumber>9780375705243</ns2:PartNumber>
<ns2:ProductGroup>Book</ns2:ProductGroup>
<ns2:ProductTypeName>ABIS_BOOK</ns2:ProductTypeName>
<ns2:PublicationDate>2002-02-05</ns2:PublicationDate>
<ns2:Publisher>Vintage</ns2:Publisher>
<ns2:ReleaseDate>2002-02-05</ns2:ReleaseDate>
<ns2:SmallImage>
<ns2:URL>http://ecx.images-amazon.com/images/I/51KJtm7pCrL._SL75_.jpg</ns2:URL>
<ns2:Height Units="pixels">75</ns2:Height>
<ns2:Width Units="pixels">49</ns2:Width>
</ns2:SmallImage>
<ns2:Studio>Vintage</ns2:Studio>
<ns2:Title>Founding Brothers: The Revolutionary Generation</ns2:Title>
</ns2:ItemAttributes>
</AttributeSets>
<Relationships/>
<SalesRankings>
<SalesRank>
<ProductCategoryId>book_display_on_website</ProductCategoryId>
<Rank>3269</Rank>
</SalesRank>
<SalesRank>
<ProductCategoryId>9681303011</ProductCategoryId>
<Rank>4</Rank>
</SalesRank>
<SalesRank>
<ProductCategoryId>4871</ProductCategoryId>
<Rank>7</Rank>
</SalesRank>
<SalesRank>
<ProductCategoryId>11086</ProductCategoryId>
<Rank>16</Rank>
</SalesRank>
</SalesRankings>
</Product>
</Products>
</GetMatchingProductForIdResult>
<GetMatchingProductForIdResult Id="VB-GNYY-PMZS" IdType="SellerSKU" status="Success">
<Products>
<Product>
<Identifiers>
<MarketplaceASIN>
<MarketplaceId>ATVPDKIKX0DER</MarketplaceId>
<ASIN>B00DQAPJSY</ASIN>
</MarketplaceASIN>
</Identifiers>
<AttributeSets>
<ns2:ItemAttributes xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd" xml:lang="en-US">
<ns2:Binding>Personal Computers</ns2:Binding>
<ns2:Brand>JBL</ns2:Brand>
<ns2:Color>Red</ns2:Color>
<ns2:Feature>Versatile, portable design</ns2:Feature>
<ns2:Feature>Five-hour, Li-ion rechargeable battery</ns2:Feature>
<ns2:Feature>Built-in microphone &amp; call answer button for mobile devices</ns2:Feature>
<ns2:Label>JBL</ns2:Label>
<ns2:ListPrice>
<ns2:Amount>119.95</ns2:Amount>
<ns2:CurrencyCode>USD</ns2:CurrencyCode>
</ns2:ListPrice>
<ns2:Manufacturer>JBL</ns2:Manufacturer>
<ns2:MediaType>MP3</ns2:MediaType>
<ns2:Model>JBLFLIPREDAM</ns2:Model>
<ns2:PackageDimensions>
<ns2:Height Units="inches">2.90</ns2:Height>
<ns2:Length Units="inches">7.50</ns2:Length>
<ns2:Width Units="inches">7.10</ns2:Width>
<ns2:Weight Units="pounds">1.70</ns2:Weight>
</ns2:PackageDimensions>
<ns2:PackageQuantity>1</ns2:PackageQuantity>
<ns2:PartNumber>JBLFLIPREDAM</ns2:PartNumber>
<ns2:ProductGroup>Network Media Player</ns2:ProductGroup>
<ns2:ProductTypeName>PORTABLE_AUDIO</ns2:ProductTypeName>
<ns2:Publisher>JBL</ns2:Publisher>
<ns2:SmallImage>
<ns2:URL>http://ecx.images-amazon.com/images/I/410I6YxfTtL._SL75_.jpg</ns2:URL>
<ns2:Height Units="pixels">65</ns2:Height>
<ns2:Width Units="pixels">75</ns2:Width>
</ns2:SmallImage>
<ns2:Studio>JBL</ns2:Studio>
<ns2:Title>JBL Flip Wireless Bluetooth Speaker (Red)</ns2:Title>
</ns2:ItemAttributes>
</AttributeSets>
<Relationships/>
<SalesRankings>
<SalesRank>
<ProductCategoryId>wireless_display_on_website</ProductCategoryId>
<Rank>17155</Rank>
</SalesRank>
</SalesRankings>
</Product>
</Products>
</GetMatchingProductForIdResult>
<ResponseMetadata>
<RequestId>c09070bd-cc9b-485b-9df0-e7ff24b014b5</RequestId>
</ResponseMetadata>
</GetMatchingProductForIdResponse>
ResponseHeaderMetadata: RequestId: c09070bd-cc9b-485b-9df0-e7ff24b014b5, ResponseContext: kTgQHamo26t53ZIXhXJTA7jfRyqcib2iqO1Wf/3khcqgfhHFseHa9JYrX8Dlzs9OrGixmPIsCxuZ jSUoBV3RLw==,YR44XTRP1f51djG65oaAWhdNHw0+6V32WmJmZoqkSTeUVHYvq88nOBfaE6EgXq3XTR9WAss6d97r gR/TimYXbQ==, Timestamp: 2014-09-15T05:23:50.364Z, Quota Max: 17772.0, Quota Remaining: 17772.0, Quota Resets At: 2014-09-15T05:25:00.000Z

Я пытаюсь получить вес каждого элемента (продукта) в ответе, который можно найти по адресу GetMatchingProductForIdResult/Products/Product/AttributeSets/ns2:ItemAttributes/ns2:ItemDimensions/ns2:Weight если вы начинаете с корневого элемента узла. Я пытаюсь использовать xpath как это:

$dozy=new DOMDocument();
$dozy->loadXML($response->toXML());

$dozy->preserveWhiteSpace = false;
$dozy->formatOutput = true;

$xpathy = new DOMXpath($dozy);

$xpathy->registerNamespace('ns2', 'http://www.w3.org/XML/2008/xsdl-exx/ns2');

$weighter = $xpathy->query('//GetMatchingProductForIdResult/Products/Product/AttributeSets/ns2:ItemAttributes/ns2:ItemDimensions/ns2:Weight');

Однако, когда я иду, чтобы ссылаться на то, что я получил с:

echo $weighter->item(0)->nodeValue;

Я получаю сообщение об ошибке:

Trying to get property of non-object.

Я думаю, что это происходит потому, что $weighter имеет значение null (в нем ничего не хранится), поэтому item функция не работает над этим.

Любая помощь о том, как нацелиться на ns2:Weight узел будет принята с благодарностью. Благодарю.

0

Решение

Что пошло не так

Ваш оригинальный запрос xpath не выполняется по нескольким причинам:

1.) Неверное пространство имен, которое вы зарегистрировали для «ns2». Важной частью является URI пространства имен — вы можете выбрать для префикса все, что захотите. Так:

$xpathy->registerNamespace(
'ns2',
"http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd");

2.) Другие элементы имеют пространство имен по умолчанию, которое необходимо зарегистрировать с префиксом в объекте DOMXPath и префиксом, используемым в выражении.

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

$weighter = $xpathy->query(
'//ns:GetMatchingProductForIdResult/ns:Products/ns:Product/ns:AttributeSets
/ns2:ItemAttributes/ns2:ItemDimensions/ns2:Weight'
);

Какие может быть быть правым

С вашего ответа Вот указывает на то, что //*[local-name()="Weight"]' отлично работает, чтобы выбрать то, что вы ищете, вы можете полностью пропустить все вещи xpath и просто использовать:

$weighter = $dozy->getElementsByTagName('Weight');

Однако вы найдете оба с getElementsByTagName() и в вашем сокращенном xpath вы получите больше элементов, чем вы получили бы из исправленной версии вашего исходного xpath.

Это потому, что оригинал искал только тех, кто //ns2:ItemDimensions/ns2:Weight где новый сокращенный путь также находит те в //ns2:PackageDimensions/ns2:Weight,


Что может быть правильнымэр

Чтобы сложить все вместе, чтобы получить результаты, которые получит оригинал, вы смотрите на что-то вроде:

$dozy=new DOMDocument();
$dozy->loadXML($response->toXML());

$dozy->preserveWhiteSpace = false;
$dozy->formatOutput = true;

$xpathy = new DOMXpath($dozy);

$xpathy->registerNamespace(
'ns2',
"http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd");
$xpathy->registerNamespace(
'ns',
"http://mws.amazonservices.com/schema/Products/2011-10-01");

$weighter = $xpathy->query(
'//ns:GetMatchingProductForIdResult/ns:Products/ns:Product/ns:AttributeSets
/ns2:ItemAttributes/ns2:ItemDimensions/ns2:Weight'
);

foreach ($weighter as $node) {
echo $node->nodeValue, "\n";
}

Или же:

(Немного короче, но все же так же специфично для данных данного образца.)

$dozy=new DOMDocument();
$dozy->loadXML($response->toXML());

$dozy->preserveWhiteSpace = false;
$dozy->formatOutput = true;

$xpathy = new DOMXpath($dozy);

$xpathy->registerNamespace(
'ns2',
"http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd");

$weighter = $xpathy->query(
'//ns2:ItemDimensions/ns2:Weight'
);

foreach ($weighter as $node) {
echo $node->nodeValue, "\n";
}

Любой из которых будет выводить:

0.60
0.70
0.51
1

Другие решения

Это сработало:

$weighter = $xpathy->query('//*[local-name()="Weight"]');

0

ns2 Префикс пространства имен в вашем XML объявлен следующим образом:

<ns2:ItemAttributes
xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd"xml:lang="en-US">

Вам необходимо зарегистрировать соответствующий URI пространства имен:

$xpathy->registerNamespace('ns2', 'http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd');
0