XMLReader区分具有相同名称的嵌套节点

时间:2020-05-27 16:45:51

标签: php xml xmlreader getattribute

尝试使用外部xml文件,该文件是这样堆叠的:

<?xml version="1.0" encoding="UTF-8"?>
<merchandiser xsi:noNamespaceSchemaLocation="merchandiser.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <header>
    <merchantId>44235</merchantId>
    <merchantName>Feelunique (UK)</merchantName>
    <createdOn>04/27/2020 00:05:33</createdOn>
  </header>
  <product part_number="99082" manufacturer_name="Sanctuary Spa" sku_number="99082" name="Sanctuary Spa Sleep Dream Easy Pillow Mist 100ml" product_id="15927186808">
    <URL>
      <product>https://click.linksynergy.com/link?id=y/LyuzvjryY&offerid=687217.15927186808&type=15&murl=https%3A%2F%2Fwww.feelunique.com%2Fp%2FSanctuary-Spa-Sleep-Dream-Easy-Pillow-Mist-100ml%26curr%3DGBP</product>
    </URL>
  </product>
</merchandiser>

您可以看到节点<product>被使用了两次,我需要从第一个获取属性,在第二个获取值。

默认情况下,我的代码似乎直接跳到第二个代码,并允许我定义第二个$xml->value节点的<product>,但是我似乎无法弄清楚如何将两者分开在我的代码中并获取所需的属性。

            while($xml->read()) {

                if($xml->nodeType == XMLReader::ELEMENT) {

                    if($xml->localName == 'header') {

                        $header = array();

                    }

                    if($xml->localName == 'merchantName') {

                        $xml->read();
                        $header['merchant'] = addslashes($xml->value);

                    }

                    if($xml->localName == 'product') {

                        $product = array();
                        $product['merchant'] = $header['merchant'];
                        $product['title'] = $xml->getAttribute('name');

                    }

                    if($xml->localName == 'product') {

                        $xml->read();
                        $product['link'] = $xml->value;

                    }
}
}

有人可以为我指出如何在我的php代码中同时实现两个值的正确方向吗?

2 个答案:

答案 0 :(得分:0)

这不是一个完整的解决方案,而只是演示如何从两个product节点中的每个节点访问元素-您可以根据需要进行修改:

$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXpath($doc);
$product = $xpath->evaluate("//product/@name");
$link = $xpath->evaluate("//product//URL//product");
foreach ($product as $node1) {
    foreach ($link as $node2){
  echo trim($node2->nodeValue), PHP_EOL,trim($node1->nodeValue);
}}

输出:

https://click.linksynergy.com...
Sanctuary Spa Sleep Dream Easy Pillow Mist 100ml

答案 1 :(得分:0)

XMLReader会从一个节点跳到另一个节点,当您点击“ product”时,两个if语句都将评估为true。

知道您在哪个产品节点上的唯一方法就是是否保留其父级的信息。

这样做会很痛苦。最好在级别1 X.509 Certificate (optional): (For Signed Request)打开之后启动一个新函数,并创建一个新的循环来解析“产品”子树。

我写了library来帮助解决这个问题。

XMLReader(和expat)可能是快速解析大型XML文档的好工具,但是您需要学习如何有效遍历嵌套结构的算法。如果您发现这太难理解了,我建议您使用一个更简单的XML解析器,例如DOM或SimpleXML。