PHP SimpleXML 解析问题,获取重复元素

PHP SimpleXML Parsing Issue, get duplicate elements

正在尝试使用 SimpleXML 函数进行解析,它工作正常。但我一直坚持如何从 XML

中提取 'colour' & 'length 数据

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

完整的 xml 文件可以从 ebay-response.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";

当我 运行 我的代码如下所示时,我得到的结果如下所示,正如您所看到的,我似乎只拉回了白色(没有长度),即使我的颜色似乎也只有从第一个 'Variation' 元素

获取颜色
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

这部分代码不会遍历 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 />';           
}

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

在 ebay 答案中你有一个 <Item> 元素。

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

那个 <Variations> 元素可以有零个或多个 <Variation> 元素。

<Variantion> 元素又可以在零个或多个 <VariationSpecifics> <NameValueList> 元素中包含 <Name>/<Value> 对。

<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()),示例中使用该元素用分号 ("[=27] 分隔 name/value 对=]").

示例(缩短)输出为:

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)

现在这并不总是您想要的显示方式。例如,您可能想要列出所有颜色,并为每种颜色显示可用尺寸。这将变得过于复杂,因为你在那里有 SimpleXMLElements。 foreach 的另一种选择是 运行 一个或多个 xpath 查询,您可以对其结果再次进行 foreach。

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

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

示例输出:

CLOSED END ZIPS 40 Colours 4  6  8 10 12in (10-30cm) for Skirt Trousers Craft
=============================================================================
 * Color White: 7 Lengths: 4" (10cm) (SKU: 1176:3448); 5" (12cm) (SKU: 1176:3449); 6" (15cm) (SKU: 1176:3450); 7" (18cm) (SKU: 1176:3451); 8" (20cm) (SKU: 1176:3452); 10" (25cm) (SKU: 1176:3453); 12" (30cm) (SKU: 1176:3454)
 * Color Ivory: 7 Lengths: 4" (10cm) (SKU: 1177:3448); 5" (12cm) (SKU: 1177:3449); 6" (15cm) (SKU: 1177:3450); 7" (18cm) (SKU: 1177:3451); 8" (20cm) (SKU: 1177:3452); 10" (25cm) (SKU: 1177:3453); 12" (30cm) (SKU: 1177:3454)
 * Color Cream: 7 Lengths: 4" (10cm) (SKU: 1178:3448); 5" (12cm) (SKU: 1178:3449); 6" (15cm) (SKU: 1178:3450); 7" (18cm) (SKU: 1178:3451); 8" (20cm) (SKU: 1178:3452); 10" (25cm) (SKU: 1178:3453); 12" (30cm) (SKU: 1178:3454)
 * Color Lemon: 7 Lengths: 4" (10cm) (SKU: 1179:3448); 5" (12cm) (SKU: 1179:3449); 6" (15cm) (SKU: 1179:3450); 7" (18cm) (SKU: 1179:3451); 8" (20cm) (SKU: 1179:3452); 10" (25cm) (SKU: 1179:3453); 12" (30cm) (SKU: 1179:3454)
 * Color Peach: 7 Lengths: 4" (10cm) (SKU: 1180:3448); 5" (12cm) (SKU: 1180:3449); 6" (15cm) (SKU: 1180:3450); 7" (18cm) (SKU: 1180:3451); 8" (20cm) (SKU: 1180:3452); 10" (25cm) (SKU: 1180:3453); 12" (30cm) (SKU: 1180:3454)
 * Color Pale Green: 7 Lengths: 4" (10cm) (SKU: 1181:3448); 5" (12cm) (SKU: 1181:3449); 6" (15cm) (SKU: 1181:3450); 7" (18cm) (SKU: 1181:3451); 8" (20cm) (SKU: 1181:3452); 10" (25cm) (SKU: 1181:3453); 12" (30cm) (SKU: 1181:3454)
 * Color Aqua: 7 Lengths: 4" (10cm) (SKU: 1182:3448); 5" (12cm) (SKU: 1182:3449); 6" (15cm) (SKU: 1182:3450); 7" (18cm) (SKU: 1182:3451); 8" (20cm) (SKU: 1182:3452); 10" (25cm) (SKU: 1182:3453); 12" (30cm) (SKU: 1182:3454)
 * Color Pale Blue: 7 Lengths: 4" (10cm) (SKU: 1183:3448); 5" (12cm) (SKU: 1183:3449); 6" (15cm) (SKU: 1183:3450); 7" (18cm) (SKU: 1183:3451); 8" (20cm) (SKU: 1183:3452); 10" (25cm) (SKU: 1183:3453); 12" (30cm) (SKU: 1183:3454)
 * Color Mid Blue: 7 Lengths: 4" (10cm) (SKU: 1184:3448); 5" (12cm) (SKU: 1184:3449); 6" (15cm) (SKU: 1184:3450); 7" (18cm) (SKU: 1184:3451); 8" (20cm) (SKU: 1184:3452); 10" (25cm) (SKU: 1184:3453); 12" (30cm) (SKU: 1184:3454)
 * Color Lilac: 7 Lengths: 4" (10cm) (SKU: 1185:3448); 5" (12cm) (SKU: 1185:3449); 6" (15cm) (SKU: 1185:3450); 7" (18cm) (SKU: 1185:3451); 8" (20cm) (SKU: 1185:3452); 10" (25cm) (SKU: 1185:3453); 12" (30cm) (SKU: 1185:3454)
 * Color Heather: 7 Lengths: 4" (10cm) (SKU: 1186:3448); 5" (12cm) (SKU: 1186:3449); 6" (15cm) (SKU: 1186:3450); 7" (18cm) (SKU: 1186:3451); 8" (20cm) (SKU: 1186:3452); 10" (25cm) (SKU: 1186:3453); 12" (30cm) (SKU: 1186:3454)
 * Color Pale Pink: 7 Lengths: 4" (10cm) (SKU: 1187:3448); 5" (12cm) (SKU: 1187:3449); 6" (15cm) (SKU: 1187:3450); 7" (18cm) (SKU: 1187:3451); 8" (20cm) (SKU: 1187:3452); 10" (25cm) (SKU: 1187:3453); 12" (30cm) (SKU: 1187:3454)
 * Color Vintage Pink: 7 Lengths: 4" (10cm) (SKU: 1189:3448); 5" (12cm) (SKU: 1189:3449); 6" (15cm) (SKU: 1189:3450); 7" (18cm) (SKU: 1189:3451); 8" (20cm) (SKU: 1189:3452); 10" (25cm) (SKU: 1189:3453); 12" (30cm) (SKU: 1189:3454)
 * Color Ruby: 7 Lengths: 4" (10cm) (SKU: 1190:3448); 5" (12cm) (SKU: 1190:3449); 6" (15cm) (SKU: 1190:3450); 7" (18cm) (SKU: 1190:3451); 8" (20cm) (SKU: 1190:3452); 10" (25cm) (SKU: 1190:3453); 12" (30cm) (SKU: 1190:3454)
 * Color Cerise: 7 Lengths: 4" (10cm) (SKU: 1191:3448); 5" (12cm) (SKU: 1191:3449); 6" (15cm) (SKU: 1191:3450); 7" (18cm) (SKU: 1191:3451); 8" (20cm) (SKU: 1191:3452); 10" (25cm) (SKU: 1191:3453); 12" (30cm) (SKU: 1191:3454)
 * Color Bright Purple: 7 Lengths: 4" (10cm) (SKU: 1193:3448); 5" (12cm) (SKU: 1193:3449); 6" (15cm) (SKU: 1193:3450); 7" (18cm) (SKU: 1193:3451); 8" (20cm) (SKU: 1193:3452); 10" (25cm) (SKU: 1193:3453); 12" (30cm) (SKU: 1193:3454)
 * Color Deep Purple: 7 Lengths: 4" (10cm) (SKU: 1194:3448); 5" (12cm) (SKU: 1194:3449); 6" (15cm) (SKU: 1194:3450); 7" (18cm) (SKU: 1194:3451); 8" (20cm) (SKU: 1194:3452); 10" (25cm) (SKU: 1194:3453); 12" (30cm) (SKU: 1194:3454)
 * Color Magenta: 7 Lengths: 4" (10cm) (SKU: 1192:3448); 5" (12cm) (SKU: 1192:3449); 6" (15cm) (SKU: 1192:3450); 7" (18cm) (SKU: 1192:3451); 8" (20cm) (SKU: 1192:3452); 10" (25cm) (SKU: 1192:3453); 12" (30cm) (SKU: 1192:3454)
 * Color Bright Red: 7 Lengths: 4" (10cm) (SKU: 1195:3448); 5" (12cm) (SKU: 1195:3449); 6" (15cm) (SKU: 1195:3450); 7" (18cm) (SKU: 1195:3451); 8" (20cm) (SKU: 1195:3452); 10" (25cm) (SKU: 1195:3453); 12" (30cm) (SKU: 1195:3454)
 * Color Cherry Red: 7 Lengths: 4" (10cm) (SKU: 1196:3448); 5" (12cm) (SKU: 1196:3449); 6" (15cm) (SKU: 1196:3450); 7" (18cm) (SKU: 1196:3451); 8" (20cm) (SKU: 1196:3452); 10" (25cm) (SKU: 1196:3453); 12" (30cm) (SKU: 1196:3454)
 * Color Orange: 7 Lengths: 4" (10cm) (SKU: 1197:3448); 5" (12cm) (SKU: 1197:3449); 6" (15cm) (SKU: 1197:3450); 7" (18cm) (SKU: 1197:3451); 8" (20cm) (SKU: 1197:3452); 10" (25cm) (SKU: 1197:3453); 12" (30cm) (SKU: 1197:3454)
 * Color Gold: 7 Lengths: 4" (10cm) (SKU: 1198:3448); 5" (12cm) (SKU: 1198:3449); 6" (15cm) (SKU: 1198:3450); 7" (18cm) (SKU: 1198:3451); 8" (20cm) (SKU: 1198:3452); 10" (25cm) (SKU: 1198:3453); 12" (30cm) (SKU: 1198:3454)
 * Color Yellow: 7 Lengths: 4" (10cm) (SKU: 1199:3448); 5" (12cm) (SKU: 1199:3449); 6" (15cm) (SKU: 1199:3450); 7" (18cm) (SKU: 1199:3451); 8" (20cm) (SKU: 1199:3452); 10" (25cm) (SKU: 1199:3453); 12" (30cm) (SKU: 1199:3455)
 * Color Bright Lime: 7 Lengths: 4" (10cm) (SKU: 1200:3448); 5" (12cm) (SKU: 1200:3449); 6" (15cm) (SKU: 1200:3450); 7" (18cm) (SKU: 1200:3451); 8" (20cm) (SKU: 1200:3452); 10" (25cm) (SKU: 1200:3453); 12" (30cm) (SKU: 1200:3454)
 * Color Emerald Green: 7 Lengths: 4" (10cm) (SKU: 1202:3448); 5" (12cm) (SKU: 1202:3449); 6" (15cm) (SKU: 1202:3450); 7" (18cm) (SKU: 1202:3451); 8" (20cm) (SKU: 1202:3452); 10" (25cm) (SKU: 1202:3453); 12" (30cm) (SKU: 1202:3454)
 * Color Forest Green: 7 Lengths: 4" (10cm) (SKU: 1203:3448); 5" (12cm) (SKU: 1203:3449); 6" (15cm) (SKU: 1203:3450); 7" (18cm) (SKU: 1203:3451); 8" (20cm) (SKU: 1203:3452); 10" (25cm) (SKU: 1203:3453); 12" (30cm) (SKU: 1203:3454)
 * Color Olive Green: 7 Lengths: 4" (10cm) (SKU: 1204:3448); 5" (12cm) (SKU: 1204:3449); 6" (15cm) (SKU: 1204:3450); 7" (18cm) (SKU: 1204:3451); 8" (20cm) (SKU: 1204:3452); 10" (25cm) (SKU: 1204:3453); 12" (30cm) (SKU: 1204:3454)
 * Color Sage Green: 7 Lengths: 4" (10cm) (SKU: 1201:3448); 5" (12cm) (SKU: 1201:3449); 6" (15cm) (SKU: 1201:3450); 7" (18cm) (SKU: 1201:3451); 8" (20cm) (SKU: 1201:3452); 10" (25cm) (SKU: 1201:3453); 12" (30cm) (SKU: 1201:3454)
 * Color Turquoise: 7 Lengths: 4" (10cm) (SKU: 1205:3448); 5" (12cm) (SKU: 1205:3449); 6" (15cm) (SKU: 1205:3450); 7" (18cm) (SKU: 1205:3451); 8" (20cm) (SKU: 1205:3452); 10" (25cm) (SKU: 1205:3453); 12" (30cm) (SKU: 1205:3454)
 * Color Denim Blue: 7 Lengths: 4" (10cm) (SKU: 1207:3448); 5" (12cm) (SKU: 1207:3449); 6" (15cm) (SKU: 1207:3450); 7" (18cm) (SKU: 1207:3451); 8" (20cm) (SKU: 1207:3452); 10" (25cm) (SKU: 1207:3453); 12" (30cm) (SKU: 1207:3454)
 * Color Royal Blue: 7 Lengths: 4" (10cm) (SKU: 1206:3448); 5" (12cm) (SKU: 1206:3449); 6" (15cm) (SKU: 1206:3450); 7" (18cm) (SKU: 1206:3451); 8" (20cm) (SKU: 1206:3452); 10" (25cm) (SKU: 1206:3453); 12" (30cm) (SKU: 1206:3454)
 * Color Navy: 7 Lengths: 4" (10cm) (SKU: 1208:3448); 5" (12cm) (SKU: 1208:3449); 6" (15cm) (SKU: 1208:3450); 7" (18cm) (SKU: 1208:3451); 8" (20cm) (SKU: 1208:3452); 10" (25cm) (SKU: 1208:3453); 12" (30cm) (SKU: 1208:3454)
 * Color Rust: 7 Lengths: 4" (10cm) (SKU: 1210:3448); 5" (12cm) (SKU: 1210:3449); 6" (15cm) (SKU: 1210:3450); 7" (18cm) (SKU: 1210:3451); 8" (20cm) (SKU: 1210:3452); 10" (25cm) (SKU: 1210:3453); 12" (30cm) (SKU: 1210:3454)
 * Color Dark Brown: 7 Lengths: 4" (10cm) (SKU: 1211:3448); 5" (12cm) (SKU: 1211:3449); 6" (15cm) (SKU: 1211:3450); 7" (18cm) (SKU: 1211:3451); 8" (20cm) (SKU: 1211:3452); 10" (25cm) (SKU: 1211:3453); 12" (30cm) (SKU: 1211:3454)
 * Color Light Grey: 7 Lengths: 4" (10cm) (SKU: 1212:3448); 5" (12cm) (SKU: 1212:3449); 6" (15cm) (SKU: 1212:3450); 7" (18cm) (SKU: 1212:3451); 8" (20cm) (SKU: 1212:3452); 10" (25cm) (SKU: 1212:3453); 12" (30cm) (SKU: 1212:3454)
 * Color Dark Grey: 5 Lengths: 4" (10cm) (SKU: 1213:3448); 5" (12cm) (SKU: 1213:3449); 6" (15cm) (SKU: 1213:3450); 7" (18cm) (SKU: 1213:3451); 8" (20cm) (SKU: 1213:3452)