我有以下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
属性有两个项目,其中我需要获取一些值。
我目前的代码是:
$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);
仅返回第一个产品的信息。如何更改它以获得两种产品?
答案 0 :(得分:1)
您只获得一个项目的问题是您只获取一个项目。
这可能听起来有点没有实际意义,以防万一,您将父元素放入$item
实际上只存在一次。
所以你没有足够深入。第一步更深入迭代正确的孩子,它就像你计划的那样工作:
$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;
}