繁体   English   中英

如何使用PHP从此Amazon XML响应文件中获取数据?

[英]How can I get data from this Amazon XML response file using PHP?

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

可悲的是,我对PHP(或XML)不是很好。 我一直在阅读/尝试在所有可以找到的所有站点上找到的所有内容,但我认为我还不能胜任这项工作。

我已经尝试过DOM,simpleXML,名称空间等,但是必须完全弄错了。

我已经尝试过以下代码片段:

    $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>";
    }

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

GetMyPriceForASINResult = xxxxxxxxxxxB07DNYLZP5USD9.97USD9.97USD0.00USD15.99AMAZONNewNewxxxxxxxxxxxxx令人眼花T乱的纹身元数据= xxxxxxxxxxxxxxxxxxxxxxxx

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

<?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)提供的链接无济于事-它本质上是信息汇编。

通常, XML相当容易使用,但是您偶然发现了使它变得更加复杂的其中一项:XML名称空间。 这是通过外部元素中xmlns属性的存在而放弃的。

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

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

<?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 ,我在这里使用过SimpleXML ,但是我希望也有一个DOMDocument解决方案。

<?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将向您显示文档中具有的名称空间,唯一的名称空间是null。 由于此字段为空,因此您的标签没有前缀字符串(例如Amazon:Product ),但名称空间仍然存在。 看起来像这样:

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

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

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

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

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
)

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

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

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

AMAZON
AMAZON

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM