如何使用PHP从此Amazon XML响应文件中获取数据? [英] How can I get data from this Amazon XML response file using PHP?

查看:64
本文介绍了如何使用PHP从此Amazon XML响应文件中获取数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何从下面显示的Amazon MWS XML文件中提取值?

How can I extract the values from the Amazon MWS XML file shown below?

可悲的是,我对PHP(或XML)不太满意.我一直在阅读/尝试在所有可以找到的所有站点上找到的所有东西,但我认为我还不能胜任这项工作.

Sadly I'm not very good with PHP (or XML). I have been reading/trying everything I can find on all sites I can find but I think I'm just not up to the job.

我已经尝试过DOM,simpleXML,名称空间等,但一定是完全搞错了.

I've tried DOM, simpleXML, namespaces etc etc but must have simply got it all wrong.

我已经尝试了以下代码段:

I've tried this snippet of code:

    $response = $service->GetMyPriceForASIN($request);

    $dom = new DOMDocument();
    $dom->loadXML($response->toXML());
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->saveXML();     

    $x = $dom->documentElement;
    foreach ($x->childNodes AS $item) {
    print $item->nodeName . " = " . $item->nodeValue . "<br>";
    }

但是,它仅从最外层节点返回此数据,如下所示:

However it only returns this data from the outermost nodes, shown here:

GetMyPriceForASINResult = xxxxxxxxxxxB07DNYLZP5USD9.97USD9.97USD0.00USD15.99AMAZONNewNewxxxxxxxxxxxxxDazzle Tattoos ResponseMetadata = xxxxxxxxxxxxxxxxxxxxxxxx

GetMyPriceForASINResult = xxxxxxxxxxxB07DNYLZP5USD9.97USD9.97USD0.00USD15.99AMAZONNewNewxxxxxxxxxxxxxDazzle Tattoos ResponseMetadata = xxxxxxxxxxxxxxxxxxxxxxxx

我只是想获得的是[Offers]节点下子代的货币和价格.

What I'm simply trying to get are the currency and prices that are the children under the [Offers] node.

<?xml version="1.0"?>
<GetMyPriceForASINResponse 
xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
  <GetMyPriceForASINResult ASIN="B07DNYLZP5" status="Success">
    <Product>
      <Identifiers>
        <MarketplaceASIN>
          <MarketplaceId>xxxxxxxxxxxxxxxxxx</MarketplaceId>
          <ASIN>B07DNYLZP5</ASIN>
        </MarketplaceASIN>
      </Identifiers>
      <Offers>
        <Offer>
          <BuyingPrice>
            <LandedPrice>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>9.97</Amount>
            </LandedPrice>
            <ListingPrice>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>9.97</Amount>
            </ListingPrice>
            <Shipping>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>0.00</Amount>
            </Shipping>
          </BuyingPrice>
          <RegularPrice>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>15.99</Amount>
          </RegularPrice>
          <FulfillmentChannel>AMAZON</FulfillmentChannel>
          <ItemCondition>New</ItemCondition>
          <ItemSubCondition>New</ItemSubCondition>
          <SellerId>xxxxxxxxxx</SellerId>
          <SellerSKU>Dazzle Tattoos</SellerSKU>
        </Offer>
      </Offers>
    </Product>
  </GetMyPriceForASINResult>
  <ResponseMetadata>
    <RequestId>xxxxxxxxxxxxxxxxxxxxx</RequestId>
  </ResponseMetadata>
</GetMyPriceForASINResponse>

更新

奈杰尔(Nigel)提供的链接无济于事-它本质上是信息汇编.

Update

The link provided by Nigel doesn't help - it is basically a compendium of information.

推荐答案

XML 一般相当容易使用,但是您偶然发现了其中一项使之更加棘手的事情: XML名称空间.这是由于外部元素中存在xmlns属性所致.

XML in general is fairly easy to work with, but you've stumbled over one of the things that makes it much tricker: XML namespaces. This is given away by the presence of the xmlns attribute in the outer element.

在查看您的文档时,我的第一个想法是,由于我不熟悉此API,因此要约"听起来可能是复数形式.因此,我修改了测试文档以允许这样做,因为<Offers>可能设计为包含零个,一个或多个一个<Offer>.

My first thought upon looking at your document was, and since I am not familiar with this API, "offers" sounds like it could be plural. I therefore modified the test document to allow for that, since <Offers> is probably designed to contain zero, one, or more than one <Offer>.

因此,出于测试目的,它看起来像这样(为方便起见,我只复制了一个<Offer>):

So, for testing purposes, that would look like this (I've just duplicated the single <Offer> for convenience):

<?xml version="1.0"?>
<GetMyPriceForASINResponse 
    xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01"
>
  <GetMyPriceForASINResult ASIN="B07DNYLZP5" status="Success">
    <Product>
      <Identifiers>
        <MarketplaceASIN>
          <MarketplaceId>xxxxxxxxxxxxxxxxxx</MarketplaceId>
          <ASIN>B07DNYLZP5</ASIN>
        </MarketplaceASIN>
      </Identifiers>
      <Offers>
        <Offer>
          <BuyingPrice>
            <LandedPrice>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>9.97</Amount>
            </LandedPrice>
            <ListingPrice>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>9.97</Amount>
            </ListingPrice>
            <Shipping>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>0.00</Amount>
            </Shipping>
          </BuyingPrice>
          <RegularPrice>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>15.99</Amount>
          </RegularPrice>
          <FulfillmentChannel>AMAZON</FulfillmentChannel>
          <ItemCondition>New</ItemCondition>
          <ItemSubCondition>New</ItemSubCondition>
          <SellerId>xxxxxxxxxx</SellerId>
          <SellerSKU>Dazzle Tattoos</SellerSKU>
        </Offer>
        <Offer>
          <BuyingPrice>
            <LandedPrice>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>9.97</Amount>
            </LandedPrice>
            <ListingPrice>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>9.97</Amount>
            </ListingPrice>
            <Shipping>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>0.00</Amount>
            </Shipping>
          </BuyingPrice>
          <RegularPrice>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>15.99</Amount>
          </RegularPrice>
          <FulfillmentChannel>AMAZON</FulfillmentChannel>
          <ItemCondition>New</ItemCondition>
          <ItemSubCondition>New</ItemSubCondition>
          <SellerId>xxxxxxxxxx</SellerId>
          <SellerSKU>Dazzle Tattoos</SellerSKU>
        </Offer>
      </Offers>
    </Product>
  </GetMyPriceForASINResult>
  <ResponseMetadata>
    <RequestId>xxxxxxxxxxxxxxxxxxxxx</RequestId>
  </ResponseMetadata>
</GetMyPriceForASINResponse>

我使用的PHP代码如下.据我所知,我在这里使用过SimpleXML,但是我希望也有一个DOMDocument解决方案.

The PHP code I used is as follows. I've used SimpleXML here, as I am familiar with it, but I expect there would be a DOMDocument solution as well.

<?php

$file = 'prices.xml';
$doc = simplexml_load_file($file);

// Examine the namespaces
$namespaces = $doc->getNamespaces(true);    
print_r($namespaces);

$nsDoc = $doc->children($namespaces['']);
$nsDoc->registerXPathNamespace('p', 'http://mws.amazonservices.com/schema/Products/2011-10-01');

$nodes = $nsDoc->xpath('//p:GetMyPriceForASINResult/p:Product/p:Offers/p:Offer');
foreach ($nodes as $node)
{
    print_r($node);
}

我的第一个print_r将向您显示文档中具有的名称空间,唯一的是空名称空间.由于此字段为空,因此您的标签没有前缀字符串(例如Amazon:Product),但命名空间仍然存在.看起来像这样:

My first print_r will show you the namespaces you have in your document, and the only one you have is the null namespace. Since this is empty, your tags are not prefixed with a string (e.g. Amazon:Product) but the namespace nevertheless still exists. That looks like this:

Array
(
    [] => http://mws.amazonservices.com/schema/Products/2011-10-01
)

然后我得到一个可以使用的命名空间版本的文档($doc->children($namespaces[''])).我还声明了名称空间的名称为p(使用registerXPathNamespace),这是一个任意名称-您可以在这里使用任何对您有意义的名称. (我确实尝试注册一个空名称(''),但这不起作用).

I then get a namespaced version of the document ($doc->children($namespaces[''])) to work with. I have also declared the name of the namespace to be p (using registerXPathNamespace) which is an arbitrary name - you can use anything here that makes sense to you. (I did try registering a null name ('') but this did not work).

最后,我按照注释中的建议使用XPath,但是由于名称空间适用于父级及其所有子级,因此我在每个标签的前面都添加了名称空间别名. (XPath基本上是XML的查询语言,对它的解释需要一本书或一本手册,因此在这里我将避免深入探讨.如果您要做的不只是XML的粗略用法,我建议在网上找到XML测试应用程序并尝试一些查询.

Finally, I use XPath as suggested in the comments, but since the namespace applies to the parent and all its children, I have added my namespace alias in front of every tag. (XPath is basically a query language for XML, and an explanation of it requires a book or a manual, so I will refrain from digging in too deeply here. If you are going to be doing more than a cursory bit of XML, I recommend finding an XML test application on the web and trying out some queries).

输出产生两个(相同的)<Offer>节点,因此:

The output produces the two (identical) <Offer> nodes, which are thus:

SimpleXMLElement Object
(
    [BuyingPrice] => SimpleXMLElement Object
        (
            [LandedPrice] => SimpleXMLElement Object
                (
                    [CurrencyCode] => USD
                    [Amount] => 9.97
                )

            [ListingPrice] => SimpleXMLElement Object
                (
                    [CurrencyCode] => USD
                    [Amount] => 9.97
                )

            [Shipping] => SimpleXMLElement Object
                (
                    [CurrencyCode] => USD
                    [Amount] => 0.00
                )

        )

    [RegularPrice] => SimpleXMLElement Object
        (
            [CurrencyCode] => USD
            [Amount] => 15.99
        )

    [FulfillmentChannel] => AMAZON
    [ItemCondition] => New
    [ItemSubCondition] => New
    [SellerId] => xxxxxxxxxx
    [SellerSKU] => Dazzle Tattoos
)
SimpleXMLElement Object
(
    [BuyingPrice] => SimpleXMLElement Object
        (
            [LandedPrice] => SimpleXMLElement Object
                (
                    [CurrencyCode] => USD
                    [Amount] => 9.97
                )

            [ListingPrice] => SimpleXMLElement Object
                (
                    [CurrencyCode] => USD
                    [Amount] => 9.97
                )

            [Shipping] => SimpleXMLElement Object
                (
                    [CurrencyCode] => USD
                    [Amount] => 0.00
                )

        )

    [RegularPrice] => SimpleXMLElement Object
        (
            [CurrencyCode] => USD
            [Amount] => 15.99
        )

    [FulfillmentChannel] => AMAZON
    [ItemCondition] => New
    [ItemSubCondition] => New
    [SellerId] => xxxxxxxxxx
    [SellerSKU] => Dazzle Tattoos
)

您也将要取消引用每个节点中的项目.为此,可以使用对象引用,然后强制转换为所需的类型.例如:

You will want to dereference items within each node too. To do that, you can use object references and then casting to the type you want. For example:

$fulfillment = (string) $node->FulfillmentChannel;
echo "$fulfillment\n";

在循环中,这将产生我们期望的值:

In the loop, this will produce the values we expect:

AMAZON
AMAZON

这篇关于如何使用PHP从此Amazon XML响应文件中获取数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆