我有一个 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
直接回答当前问题:
所以我想获取此 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;
}
}
}