PHP迭代具有无效结构的XML文件

时间:2018-06-18 07:05:40

标签: php xml

如何迭代XML文件,如下所示?它没有任何根或父节点的输出。有些元素重复,但有些元素不重复。而且,它是传统应用程序的大文件输出。

<name>Chair</name>
<price>$53</price>
<quantity>20</quantity>
<units>Piece</units>
<name>Lamp</name>
<price>$20</price>
<quantity>90</quantity>
<units>Piece</units>
<name>Table</name>
<price>$35</price>
<quantity>10</quantity>
<units>Piece</units>
<material>Wood</material>
<name>Pen Holder</name>
<price>$5</price>
<quantity>20</quantity>
<units>Piece</units>
<color>Black</color>

这就是我这样做的方式,但它无法解决这个问题。

$data=simplexml_load_file("inventory.xml");

foreach($data->item as $item) {
        echo "Name: " . $item->name . "<br>";
        echo "Price: " . $item->price . "<br>";
        echo "Quantity: " . $item->quantity . "<br>";
        echo "Units: " . $item->units . "<br>";
        echo "Color: " . $item->color . "<br>";
}

1 个答案:

答案 0 :(得分:2)

添加根元素很容易。您只需将XML加载到字符串中,然后根据需要追加和前置。但是,对项目中的各种元素进行分组有点棘手,很大程度上取决于XML。以下代码适用于您显示的XML:

<?php

$xml = 'your xml from the question';

$dom = new DOMDocument;
$dom->loadXml("<root>$xml</root>");

$fixed = new DOMDocument();
$fixed->loadXML("<inventory><items/></inventory>");
$fixed->formatOutput = true;

$items = $fixed->getElementsByTagName('items')->item(0);
foreach ($dom->documentElement->childNodes as $node) {
    if ($node->nodeName === 'name') {
        $item = $fixed->createElement('item');
        $item->appendChild($fixed->createElement($node->nodeName, $node->nodeValue));
        $next = $node->nextSibling;
        while ($next !== null) {
            if ($next instanceof DOMElement) {
                if ($next->nodeName !== 'name') {
                    $item->appendChild($fixed->createElement($next->nodeName, $next->nodeValue));
                } else {
                    $items->appendChild($item);
                    break;
                }
            }
            $next = $next->nextSibling;
        }
    }
}
echo $fixed->saveXML();

这将创建两个文档:

  1. 带有虚拟<root>元素的旧XML,以便我们可以处理它
  2. 包含根元素<inventory>和空元素<items>的文档。
  3. 然后我们将迭代遗留XML中的所有元素。当我们找到<name>元素时,我们会创建一个新的<item>元素,并将<name>元素添加为子元素。然后我们检查每个兄弟后面的<name>元素。如果它不是<name>元素,我们也会将其添加到<item>。当它是另一个<name>时,我们会将<item>添加到<items>集合并重新开始。

    然后会产生:

    <?xml version="1.0"?>
    <inventory>
      <items>
        <item>
          <name>Chair</name>
          <price>$53</price>
          <quantity>20</quantity>
          <units>Piece</units>
        </item>
        <item>
          <name>Lamp</name>
          <price>$20</price>
          <quantity>90</quantity>
          <units>Piece</units>
        </item>
        <item>
          <name>Table</name>
          <price>$35</price>
          <quantity>10</quantity>
          <units>Piece</units>
          <material>Wood</material>
        </item>
      </items>
    </inventory>
    

    您可以在一个文档中完成所有这些操作。我觉得用两个文件更容易理解。