PHP getDocNamespaces()函数讲解
在处理XML文档时,命名空间(Namespace)是避免元素或属性名冲突的重要机制。PHP的SimpleXML扩展提供了getDocNamespaces()函数,用于获取XML文档中声明的所有命名空间,帮助开发者快速解析带命名空间的XML内容。
函数基本定义
getDocNamespaces()是SimpleXMLElement类的成员方法,用于返回当前XML文档中定义的所有命名空间及其对应的前缀。函数语法如下:
array getDocNamespaces ([ bool $recursive = FALSE ] )
参数说明:
recursive:可选参数,默认为
FALSE。如果设置为TRUE,函数会递归遍历文档的所有子节点,返回所有层级中声明的命名空间;如果为FALSE,仅返回根节点声明的命名空间。
返回值:函数返回一个关联数组,键为命名空间的前缀,值为命名空间的URI。如果某个命名空间没有前缀(即默认命名空间),则键为空的字符串。
基础使用示例
下面通过一个简单的XML文档示例,演示getDocNamespaces()的基本用法:
<?php // 定义包含命名空间的XML字符串 $xmlString = <<<XML <?xml version="1.0" encoding="UTF-8"?> <root xmlns:ns1="https://www.ipipp.com/ns1" xmlns="https://www.ipipp.com/default-ns"> <ns1:item>测试内容1</ns1:item> <child>测试内容2</child> </root> XML; // 创建SimpleXMLElement对象 $xml = new SimpleXMLElement($xmlString); // 获取根节点的命名空间 $namespaces = $xml->getDocNamespaces(); print_r($namespaces); ?>
上述代码的运行结果如下:
Array ( [ns1] => https://www.ipipp.com/ns1 [] => https://www.ipipp.com/default-ns )
可以看到,结果数组中包含了根节点声明的两个命名空间:前缀为ns1的命名空间和没有前缀的默认命名空间。
递归参数使用场景
当XML文档的命名空间不是在根节点统一声明,而是在子节点单独声明时,需要使用recursive参数获取所有命名空间。示例如下:
<?php $xmlString = <<<XML <?xml version="1.0" encoding="UTF-8"?> <root> <child xmlns:ns2="https://www.ipipp.com/ns2"> <ns2:sub>子节点命名空间内容</ns2:sub> </child> <ns3:item xmlns:ns3="https://www.ipipp.com/ns3">另一子节点内容</ns3:item> </root> XML; $xml = new SimpleXMLElement($xmlString); // 不递归获取,仅返回根节点的命名空间 $noRecursive = $xml->getDocNamespaces(); echo "非递归结果:n"; print_r($noRecursive); echo "n"; // 递归获取所有命名空间 $recursive = $xml->getDocNamespaces(TRUE); echo "递归结果:n"; print_r($recursive); ?>
运行结果如下:
非递归结果: Array ( ) 递归结果: Array ( [ns2] => https://www.ipipp.com/ns2 [ns3] => https://www.ipipp.com/ns3 )
可以看到,根节点没有声明任何命名空间,因此非递归调用返回空数组;而递归调用会遍历所有子节点,返回所有声明的命名空间。
结合命名空间解析XML内容
获取到命名空间之后,可以结合children()或xpath()方法解析带命名空间的XML元素。示例如下:
<?php
$xmlString = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:book="https://www.ipipp.com/book-ns">
<book:info>
<book:name>PHP开发实战</book:name>
<book:price>89.00</book:price>
</book:info>
</root>
XML;
$xml = new SimpleXMLElement($xmlString);
$namespaces = $xml->getDocNamespaces();
// 使用命名空间前缀获取子元素
$bookNs = $xml->children($namespaces['book']);
$bookInfo = $bookNs->info;
echo "书名:" . $bookInfo->name . "n";
echo "价格:" . $bookInfo->price . "n";
// 也可以使用xpath查询带命名空间的元素
$priceNodes = $xml->xpath('//book:price');
echo "通过xpath获取价格:" . (string)$priceNodes[0] . "n";
?>运行结果如下:
书名:PHP开发实战 价格:89.00 通过xpath获取价格:89.00
注意事项
如果XML文档中没有声明任何命名空间,调用
getDocNamespaces()会返回空数组。默认命名空间的键为空字符串,访问时需要注意避免键名错误。
getDocNamespaces()仅返回文档中声明的命名空间,不会返回未使用的前缀或者仅在特定节点临时使用的命名空间(除非开启递归)。该函数仅适用于SimpleXML扩展处理的XML文档,如果是使用DOMDocument处理XML,需要使用
DOMDocument::getElementsByTagNameNS()或者DOMNode::lookupNamespaceURI()等方法获取命名空间信息。