PHP SimpleXML Parsing Issue,获取重复元素

时间:2015-08-05 11:11:58

标签: php xml xml-parsing simplexml ebay-api

尝试使用SimpleXML函数进行解析,该函数运行正常。但我一直坚持如何提取'颜色'和' '来自XML的长度数据

下面是代码中引用的'ebay-response.xml'文件的片段:

可以从ebay-response.xml

下载完整的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<GetItemResponse xmlns="urn:ebay:apis:eBLBaseComponents">
  <Timestamp>2015-08-03T11:45:56.061Z</Timestamp>
  <Ack>Success</Ack>
  <Version>927</Version>
  <Build>E927_INTL_API_17590342_R1</Build>
  <Item>
    <Quantity>25000</Quantity>
    <ShippingDetails />
    <Title>CLOSED END ZIPS 40 Colours 4  6  8 10 12in (10-30cm) for Skirt Trousers Craft</Title>
    <Variations>
      <Variation>
        <SKU>1176:3448</SKU>
        <Quantity>100</Quantity>
        <VariationSpecifics>
          <NameValueList>
            <Name>Colour</Name>
            <Value>White</Value>
          </NameValueList>
          <NameValueList>
            <Name>Length</Name>
            <Value>4" (10cm)</Value>
          </NameValueList>
        </VariationSpecifics>
      </Variation>
      <Variation>
        <SKU>1176:3449</SKU>
        <Quantity>100</Quantity>
        <VariationSpecifics>
          <NameValueList>
            <Name>Colour</Name>
            <Value>White</Value>
          </NameValueList>
          <NameValueList>
            <Name>Length</Name>
            <Value>5" (12cm)</Value>
          </NameValueList>
        </VariationSpecifics>
      </Variation>
      <Variation>
        <SKU>1176:3450</SKU>
        <Quantity>100</Quantity>
        <VariationSpecifics>
          <NameValueList>
            <Name>Colour</Name>
            <Value>White</Value>
          </NameValueList>
          <NameValueList>
            <Name>Length</Name>
            <Value>6" (15cm)</Value>
          </NameValueList>
        </VariationSpecifics>
      </Variation>
      <Variation>
        <SKU>1176:3451</SKU>
        <Quantity>100</Quantity>
        <VariationSpecifics>
          <NameValueList>
            <Name>Colour</Name>
            <Value>White</Value>
          </NameValueList>
          <NameValueList>
            <Name>Length</Name>
            <Value>7" (18cm)</Value>
          </NameValueList>
        </VariationSpecifics>
      </Variation>
      <Variation>

我当前的PHP脚本是:

if(!$resp = simplexml_load_file("ebay-response.xml"))
{
echo "Unable to load XML Stream from eBAY API, possible no response from eBay?<br />\n";
    return;
}

if ($resp->Ack != "Success") {
echo 'eBay Response Status was: ' . $resp->Ack . " Unable to parse the XML <br />\n";
    return;
}

echo 'eBay Response Status: ' . $resp->Ack . "<br />\n";
echo 'ebay Response Timestamp: ' . $resp->Timestamp . "<br />\n";
echo 'ebay API Version: ' . $resp->Version . "<br />\n";
echo 'ebay API Build: ' . $resp->Build . "<br />\n";

echo 'eBay Item Title: ' . $resp->Item->Title . "<br />\n";
echo 'Total Items (all variations): ' . $resp->Item->Quantity . "<br />\n<br />\n";

foreach( $resp->Item->Variations->children() as $SkuAndQuantity )
{
echo 'Title: ' . $resp->Item->Title . ' SKU: ' . $SkuAndQuantity->SKU .
         ' Qty: ' . $SkuAndQuantity->Quantity . "<br />\n";
    foreach( $resp->Item->Variations->Variation->VariationSpecifics->NameValueList->children() as $options )
{
echo $options .'<br />';
}
}
echo "<br />\n";

当我运行我的代码时我得到的信息如下所示,你可以看到我似乎只是拉回了白色(并且没有长度),即使颜色我看起来只是从第一个获得颜色'变化'元素

eBay Response Status: Success
ebay Response Timestamp: 2015-08-03T11:45:56.061Z
ebay API Version: 927
ebay API Build: E927_INTL_API_17590342_R1
eBay Item Title: CLOSED END ZIPS 40 Colours 4 6 8 10 12in (10-30cm) for Skirt Trousers Craft
Total Items (all variations): 25000

Title: CLOSED END ZIPS 40 Colours 4 6 8 10 12in (10-30cm) for Skirt Trousers Craft SKU: 1176:3448 Qty: 100
Colour
White
Title: CLOSED END ZIPS 40 Colours 4 6 8 10 12in (10-30cm) for Skirt Trousers Craft SKU: 1176:3449 Qty: 100
Colour
White
Title: CLOSED END ZIPS 40 Colours 4 6 8 10 12in (10-30cm) for Skirt Trousers Craft SKU: 1176:3450 Qty: 100
Colour
White
Title: CLOSED END ZIPS 40 Colours 4 6 8 10 12in (10-30cm) for Skirt Trousers Craft SKU: 1176:3451 Qty: 100
Colour
White
Title: CLOSED END ZIPS 40 Colours 4 6 8 10 12in (10-30cm) for Skirt Trousers Craft SKU: 1176:3452 Qty: 100
Colour
White
Title: CLOSED END ZIPS 40 Colours 4 6 8 10 12in (10-30cm) for Skirt Trousers Craft SKU: 1176:3453 Qty: 100
Colour
White
Title: CLOSED END ZIPS 40 Colours 4 6 8 10 12in (10-30cm) for Skirt Trousers Craft SKU: 1176:3454 Qty: 100
Colour

2 个答案:

答案 0 :(得分:3)

XML允许以分层方式表示数据,也可以作为某种树。

在易趣答案中,您有一个<Item>元素。

<Item>元素可以有一个<Variations>元素。

<Variations>元素可以包含零个或多个<Variation>元素。

然后,<Variantion>个元素可以在零个或多个<Name> <Value>个元素中再次拥有<VariationSpecifics> / <NameValueList>个对。

<GetItemResponse>
  <Item> (1)
    <Variations> (1)
      <Variation> (1..n)
        <VariationSpecifics> (1)
          <NameValueList>  (1..n)
            <Name> (1)
            <Value> (1)

对于可以有多个条目(1..n)的元素,您需要进行迭代。

以下是纯文本输出的这种迭代的示例(因为它更容易用于演示目的):

$xml = simplexml_load_file('ebay-response.xml');
$item = $xml->Item; // one <Item>
$variations = $item->Variations->Variation; // one or more <Variation>

echo $item->Title, "\n";
echo str_repeat('=', strlen($item->Title)), "\n";

foreach ($variations as $variation) {
    echo " * ";
    $nameValues = new CachingIterator(new IteratorIterator($variation->VariationSpecifics->NameValueList));
    foreach ($nameValues as $pair) {
        echo $pair->Name, ': ', $pair->Value, $nameValues->hasNext() ? '; ' : ' ';
    }
    echo '(SKU: ', $variation->SKU, ')', "\n";
}

它表明您需要将多个foreach堆叠到一起。这里有两个 - 因为在上面的模式中有两个标有(1..n)的元素。

内部foreach有点特殊,因为我将<NameValueList>元素包含在 CachingIterator 中。那个添加了一个很好的方法,你可以问一下foreach循环中是否有下一个元素($nameValues->hasNext()),在示例中使用它来用分号分隔名称/值对(&#34; {{ 1}}&#34)

示例性(缩短的)输出是:

;

现在这并不总是你想要的显示器。例如,您可能希望列出所有颜色以及要显示可用尺寸的每种颜色。对于你在那里的 SimpleXMLElement 的foreach,这将变得过于复杂。 foreach的替代方法是运行一个或多个xpath查询,您可以再次查询结果。

这是另一个按颜色列出所有长度的例子:

CLOSED END ZIPS 40 Colours 4  6  8 10 12in (10-30cm) for Skirt Trousers Craft
=============================================================================
 * Colour: White; Length: 4" (10cm) (SKU: 1176:3448)
 * Colour: White; Length: 5" (12cm) (SKU: 1176:3449)
 * Colour: White; Length: 6" (15cm) (SKU: 1176:3450)
...
 * Colour: Dark Grey; Length: 6" (15cm) (SKU: 1213:3450)
 * Colour: Dark Grey; Length: 7" (18cm) (SKU: 1213:3451)
 * Colour: Dark Grey; Length: 8" (20cm) (SKU: 1213:3452)

示例性输出:

$item->registerXPathNamespace('xs', 'urn:ebay:apis:eBLBaseComponents');
$colors  = $item->xpath('xs:Variations//xs:Value[preceding-sibling::xs:Name = "Colour"]');
$colors  = array_unique(array_map('trim', $colors));

foreach($colors as $color) {
    echo " * Color ", $color, ": ";
    $colorLengths = $item->xpath(sprintf(
        '  xs:Variations
             //xs:Value [. = %s and preceding-sibling::xs:Name = "Colour"]
         /../..//xs:Value [preceding-sibling::xs:Name = "Length"]', xpath_string($color)));
    $count = count($colorLengths);
    echo "$count Lengths: ";
    foreach ($colorLengths as $i => $length) {
        $hasNext = $count - $i - 1;
        $length->registerXPathNamespace('xs', 'urn:ebay:apis:eBLBaseComponents');
        echo $length, ' (SKU: ', $length->xpath('../../../xs:SKU')[0], ')', $hasNext ? '; ' : '';
    }
    echo "\n";
}

答案 1 :(得分:0)

这部分代码不会迭代Variation或NameValueList元素:

foreach($resp->Item->Variations->Variation->VariationSpecifics->NameValueList->children() as $options)
{
  echo $options .'<br />';
} 

它将始终使用第一个Variation元素和第一个NameValueList元素。这会导致您的问题。

您需要将代码更改为:

foreach($resp->Item->Variations->children() as $Variation)
{
  echo 'Title: ' . $resp->Item->Title . ' SKU: ' . $Variation->SKU .' Qty: ' . $Variation->Quantity .'<br />';
  foreach($Variation->VariationSpecifics->children() as $NameValueList)
    foreach($NameValueList->children() as $option)
      echo $option .'<br />';           
}