如何从下面显示的Amazon MWS XML文件中提取值?
可悲的是,我对PHP(或XML)不太满意。我一直在阅读/尝试在所有可以找到的所有站点上找到的所有内容,但我认为我还不能胜任这项工作。
我已经尝试过DOM,simpleXML,名称空间等,但一定是完全搞错了。
我已经尝试了以下代码段:
- (sometext) a-z,[space]A-Z
但是,它仅从最外层节点返回此数据,如下所示:
GetMyPriceForASINResult = xxxxxxxxxxxB07DNYLZP5USD9.97USD9.97USD0.00USD15.99AMAZONNewNewxxxxxxxxxxxxx刺青 ResponseMetadata = xxxxxxxxxxxxxxxxxxxxxxxx
我只是想获得的是[Offers]节点下子代的货币和价格。
$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>";
}
奈杰尔(Nigel)提供的链接无济于事-它本质上是信息汇编。
答案 0 :(得分:0)
XML 总体上相当容易使用,但是您偶然发现了其中一项更加棘手的事情:XML名称空间。这是由于外部元素中configuration.CreateMap<CustomerDto, Customer>()
.AfterMap<CustomerAction>().ReverseMap();
public class CustomerAction : IMappingAction<CustomerDto, Customer>
{
private readonly IObjectMapper _objectMapper;
public CustomerAction(IObjectMapper objectMapper)
{
_objectMapper = objectMapper;
}
public void Process(CustomerDto customerDto, Customer customer)
{
}
}
属性的存在所致。
在查看您的文档时,我的第一个想法是,由于我不熟悉此API,因此“报价”听起来可能是复数形式。因此,我修改了测试文档以允许这样做,因为xmlns
可能设计为包含零个,一个或多个一个<Offers>
。
因此,出于测试目的,它看起来像这样(为方便起见,我仅复制了一个<Offer>
):
<Offer>
我使用的PHP代码如下。据我所知,我在这里使用过<?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>
,但我希望也有一个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
),但名称空间仍然存在。看起来像这样:
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";