如何从XML文件中选择所有元素的名称及其数量?

问题描述 投票:0回答:1

我有一个 XML 文件的链接。

我是这样理解的:

$xml = simplexml_load_file('http://example.com');
SimpleXMLElement {#1631 ▼
  +"@attributes": array:1 [▶]
  +"shop": SimpleXMLElement {#1605 ▼
    +"name": "Site name"
    +"company": "Thomas Munz"
    +"url": "https://example.com"
    +"currencies": SimpleXMLElement {#1606 ▶}
    +"categories": SimpleXMLElement {#1607 ▶}
    +"offers": SimpleXMLElement {#1608 ▼
      +"offer": array:24403 [▶]
    }
  }
}

这些 XML 文件将会发生变化,其中的值也会发生变化。我无法提前知道所有元素的名称。 所以我想获取此 XML 文件中所有元素的数组及其计数。 那就是:

$array = [
   'attributes' => '1',
   'shop' => '1',
   'name' => '1',
   ...
   'offer' => '24403',
]

我真的不知道该怎么做:c

php xml xmlreader
1个回答
0
投票

直接回答当前问题:

所以我想获取此 XML 文件中所有元素的数组及其计数。

要对所有元素进行计数,无论其嵌套级别如何,请使用 XPath 表达式

//*
获取所有元素,然后使用映射对它们进行计数,例如:

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

$elements = [];
foreach ($xml->xpath('//*') as $element) {
    $name = $element->getName();
    $elements[$name] = ($elements[$name] ?? 0) + 1;
}

print_r($elements);

对于以下 XML:

<?xml version="1.0"?>
<shop>
    <name>Shop name</name>
    <company>Company name</company>
    <url>https://example.com/shop</url>
    <url>https://example.com/shop2</url>
    <url>https://example.com/shop3</url>
    <currencies>
        <currency>
            <name>XXX</name>
        </currency>
        <currency>
            <name>YYY</name>
        </currency>
        <currency>
            <name>ZZZ</name>
        </currency>
    </currencies>
</shop>

上面的 PHP 代码打印:

Array
(
    [shop] => 1
    [name] => 4
    [company] => 1
    [url] => 3
    [currencies] => 1
    [currency] => 3
)

但是,如果嵌套很重要(例如,标签的名称在不同级别可能相同)或者需要更复杂的逻辑,我建议使用类似于以下的递归函数:

/**
 * @param array<string, int> $elements
 */
function countElements(SimpleXMLElement $root, array &$elements): void
{
    $elements[$root->getName()] = ($elements[$root->getName()] ?? 0) + 1;

    foreach ($root as $element) {
        $name = $element->getName();

        switch ($name) {
            case 'shop': // no break
            case 'currencies':
                countElements($element, $elements);
                break;
            case 'currency': // no break
            case 'company': // no break
            case 'name': // no break
            case 'url': // no break
                $elements[$name] = ($elements[$name] ?? 0) + 1;
                break;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.