私は次のXMLを持っています:
<?xml version="1.0" encoding="Windows-1250"?>
<rsp:responsePack version="2.0" id="Za001" state="ok" note="" programVersion="10600.125 E1 (22.1.2014)"
xmlns:rsp="http://www.stormware.cz/schema/version_2/response.xsd"
xmlns:lst="http://www.stormware.cz/schema/version_2/list.xsd"
xmlns:lStk="http://www.stormware.cz/schema/version_2/list_stock.xsd"
xmlns:stk="http://www.stormware.cz/schema/version_2/stock.xsd">
<rsp:responsePackItem version="2.0" id="a55" state="ok">
<lStk:listStock version="2.0" dateTimeStamp="2014-04-18T22:36:44" dateValidFrom="2014-04-18" state="ok">
<lStk:stock version="2.0">
<stk:stockHeader>
<stk:id>101</stk:id>
<stk:EAN>8594011770127</stk:EAN>
<stk:isSales>true</stk:isSales>
<stk:name>Item1</stk:name>
<stk:categories>
<stk:idCategory>5</stk:idCategory>
<stk:idCategory>6</stk:idCategory>
</stk:categories>
</stk:stockHeader>
</lStk:stock>
<lStk:stock version="2.0">
<stk:stockHeader>
<stk:id>114</stk:id>
<stk:EAN>8595557507840</stk:EAN>
<stk:name>Item2</stk:name>
<stk:categories>
<stk:idCategory>6</stk:idCategory>
<stk:idCategory>9</stk:idCategory>
<stk:idCategory>1</stk:idCategory>
</stk:categories>
</stk:stockHeader>
</lStk:stock>
</lStk:listStock>
</rsp:responsePackItem>
</rsp:responsePack>
lStk:stock
属性を持つアイテムが2つあり、それぞれについていくつかの値を取得する必要があります。
私の現在のコードは次のとおりです。
$xml=simplexml_load_file("import.xml");
if ($xml) {
$ns = $xml->getDocNamespaces();
$data = $xml->children($ns['rsp']);
$items = $data->children($ns['lStk']);
foreach ($items as $item) {
$counter = 0;
$elements = $item->children($ns['lStk'])->children($ns['stk'])->children($ns['stk']);
$products[$counter]['ean'] = $elements->EAN;
$products[$counter]['name'] = $elements->name;
$products[$counter]['count'] = $elements->count;
$i = 0;
foreach ($elements->categories as $category) {
/** @var $ class_name */
foreach ($category as $cat) {
/** @var $cat class_name */
$products[$counter]['category'][$i] = $cat;
$i++;
}
}
}
}
var_dump($products);
これは、最初の製品の情報のみを返します。両方の製品を入手するには、どのように変更すればよいですか?
アイテムが1つしかないという問題は、アイテムを1つだけフェッチすることです。
これは少し議論の余地があるように聞こえるかもしれませんが、場合によっては、$item
実際には1回だけ存在する親要素を配置しているということです。
ですから、あなたは十分に深く踏み込んでいません。もう1つ深くステップして、正しい子を繰り返し処理すると、計画どおりに機能します。
$xml = simplexml_load_file($path_to_xml_file);
$ns = $xml->getDocNamespaces();
$data = $xml->children($ns['rsp']);
$list = $data->children($ns['lStk']); // first the list
$items = $list->children($ns['lStk']); // then the items in that list
$products = [];
foreach ($items as $item)
{
$elements = $item->children($ns['stk'])->children($ns['stk']);
// ^^^ one less here compared to yours
$product = array_intersect_key((array)$elements, ['EAN' => 0, 'name' => 1]);
foreach ($elements->categories as $category) foreach ($category as $cat)
$product['category'][] = (string)$cat
;
$products[] = $product;
}
var_dump($products);
出力:
array(2) {
[0] => array(3) {
'EAN' => string(13) "8594011770127"
'name' => string(5) "Item1"
'category' => array(2) {
[0] => string(1) "5"
[1] => string(1) "6"
}
}
[1] => array(3) {
'EAN' => string(13) "8595557507840"
'name' => string(5) "Item2"
'category' => array(3) {
[0] => string(1) "6"
[1] => string(1) "9"
[2] => string(1) "1"
}
}
}
コードはあなたのものとは少し異なりますが、それは単なる見た目です。ただし、配列を使用するだけで$count
、$i++
やりすぎないようにする方法がいくつかわかります。
XML-Namespaceとsimplexmlを特にトラバーサルで使いやすくするために、通常、xpathはここで劇的に役立ちます。
$xml = simplexml_load_file($path_to_xml_file);
$products = [];
$items = $xml->xpath('//lStk:listStock//stk:stockHeader');
foreach ($items as $item)
{
$product = array_intersect_key((array)$item->children('stk', TRUE), ['EAN' => 0, 'name' => 1]);
$product['category'] = array_map('intval', $item->xpath('*[local-name()="categories"]/*'));
$products[] = $product;
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加