按子节点值过滤XML元素

时间:2019-04-19 20:15:02

标签: php xml simplexml

我有一个带有产品的提要,所有产品都有一个带有值的名为“类别”的子节点。我找不到一种方法来退还具有特定类别值的所有产品。

XML看起来像这样

<product>
    <name>xxxx</name>
    <category>Category A</category>
</product>
<product>
    <name>xxxx</name>
    <category>Category B</category>
</product>
<product>
    <name>xxxx</name>
    <category>Category A</category>
</product>
<product>
    <name>xxxx</name>
    <category>Category B</category>
</product>
<product>
    <name>xxxx</name>
    <category>Category B</category>
</product> 

我曾尝试使用以下PHP代码遍历XML:

$xml = simplexml_load_file('file.xml');

foreach ($xml as $product) {

    if ((string) $product['category'] == 'Category A') {
        echo (string) $product['name'];
    }

}

预期结果是返回/回显该产品的其他子节点。最好的方法是什么?

1 个答案:

答案 0 :(得分:0)

您的方法听起来不错,我对SimpleXML不够熟悉,无法说明为什么它不起作用。 但是,因为您要求最好的方法,所以我本人只喜欢DomDocument和XPath:

$xml = <<< XML
<?xml version="1.0"?>
<products>
    <product>
        <name>xxxx</name>
        <category>Category A</category>
    </product>
    <product>
        <name>xxxx</name>
        <category>Category B</category>
    </product>
    <product>
        <name>xxxx</name>
        <category>Category A</category>
    </product>
    <product>
        <name>xxxx</name>
        <category>Category B</category>
    </product>
    <product>
        <name>xxxx</name>
        <category>Category B</category>
    </product>
</products>
XML;

$dom = new DomDocument;
$dom->loadXML($xml);
$xpath = new DomXPath($dom);
$search = "Category A";
$nodes = $xpath->query("//product[category='$search']/name");

foreach ($nodes as $node) {
    printf("%s\n", $node->textContent);
}

对于SimpleXML,稍加挖掘后,它似乎需要使用对象表示法而不是数组表示法访问元素。这对我有用:

$x = simplexml_load_string($xml);
foreach ($x->product as $product) {
    if ((string) $product->category == 'Category A') {
        echo (string) $product->name;
    }
}

但是我坚持认为,从长远来看,学习DOM和XPath方法将为您提供更好的服务;它们都是在多种语言中使用的公认标准。不能将有关SimpleXML的知识转移到另一个环境。