如何在PHP Xpath中获取带有名称空间前缀的元素名称

时间:2017-07-12 09:16:06

标签: php xml xpath

我正在使用 PHP xpath 来读取XML我希望获取XML中所有元素的名称

示例XML:

<?xml version="1.0" encoding="US-ASCII" ?>
<main:docs xmlns:admin="someval" xmlns:system="someval" xmlns:links="someval">
    <admin:a someattributes>value<admin:a>
    <admin:b someattributes>value<admin:b>
    <system:c someattributes>value<system:c>
    <links:d someattributes>value<system:d>
</main:docs>

我想要名称为admin的所有元素名称的列表:a,admin:b,system:c,links:d

我正在使用以下代码

$xpath = $xml->xpath('//main:docs/*');

$arr = array();

foreach ($xpath as $child)
{
    $arr = $child->getName();
}

echo '<pre>'; print_r($arr);

但它返回a,b,c,d,没有名称空间前缀

2 个答案:

答案 0 :(得分:1)

对于每个元素,您可以获取与之关联的名称空间。这是一个数组,如

Array
(
    [admin] => someval
)

因此,您需要从中提取第一个键以获取元素的命名空间...

    foreach ($xpath as $child)
    {
        $arr[] = array_keys($child->getNameSpaces())[0].':'.$child->getName();
    }
    echo '<pre>'; 
    print_r($arr);

...给出

<pre>Array
(
    [0] => admin:a
    [1] => admin:b
    [2] => system:c
    [3] => links:d
)

答案 1 :(得分:0)

&#34; someval&#34;值是真正的命名空间。 &#34; admin&#34;,&#34; system&#34;和&#34;链接&#34;只是文档中的别名/前缀。它们是可选的,可以在任何元素节点上更改。

为命名空间注册自己的前缀,在Xpath表达式中使用前缀。

$xml = <<<'XML'
<?xml version="1.0" encoding="US-ASCII" ?>
<main:docs xmlns:main="urn:main" xmlns:admin="urn:admin" xmlns:system="urn:system" xmlns:links="urn:links">
    <admin:a>value</admin:a>
    <admin:b>value</admin:b>
    <system:c>value</system:c>
    <links:d>value</links:d>
</main:docs>
XML;

$xmlns = [
  'm' => "urn:main",
  'a' => "urn:admin",
  's' => "urn:system",
  'l' => "urn:links", 
];

$mainDocs = new SimpleXMLElement($xml);
foreach ($xmlns as $prefix => $namespace) {
  $mainDocs->registerXpathNamespace($prefix, $namespace);
}

$docChildren = $mainDocs->xpath('//m:docs/*');

$array = [];
foreach ($docChildren as $child) {
    $array[] = $child->getName();
}

echo var_dump($array);