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

niwlg2el  于 2023-09-29  发布在  PHP
关注(0)|答案(1)|浏览(89)

我有一个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

kmynzznz

kmynzznz1#

直接回答这个问题,就像现在所说的那样:
所以我想得到这个XML文件中所有元素的数组,以及它们的计数。
要对所有元素进行计数,而不管它们的嵌套级别如何,请使用XPath表达式//*获取所有元素,然后使用Map对它们进行计数,例如:

$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;
        }
    }
}

相关问题