PHP - SimpleXML foreach

时间:2014-05-07 07:04:52

标签: php xml simplexml

我有以下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);

仅返回第一个产品的信息。如何更改它以获得两种产品?

1 个答案:

答案 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;
}