Фильтрация элементов XML по значению дочернего узла - PullRequest
1 голос
/ 19 апреля 2019

У меня есть лента с продуктами, у всех продуктов есть дочерний узел со значением «категория» со значением. Я не могу найти способ вернуть все товары с определенной категорией.

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> 

Я попытался перебрать XML-код, используя следующий код PHP:

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

foreach ($xml as $product) {

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

}

Ожидаемый результат - возврат / вывод других дочерних узлов для этого продукта. Каков наилучший подход для этого?

1 Ответ

0 голосов
/ 20 апреля 2019

Ваш подход кажется здравым, я недостаточно знаком с 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 - это не то, что вы можете перенести в другую среду.

...