IMS*_*SoP 7 php simplexml xml-namespaces
这个问题旨在作为回答一个特别常见的问题的参考,这个问题可能有不同的形式:
如果您的问题已作为此问题的副本关闭,则可能与这些示例不同,但此页面应告诉您需要了解的内容.
这是一个说明性的例子:
$xml = '
<?xml version="1.0" encoding="utf-8"?>
<document xmlns="http://example.com" xmlns:ns2="https://namespaces.example.org/two" xmlns:seq="urn:example:sequences">
<list type="short">
<ns2:item seq:position="1">A thing</ns2:item>
<ns2:item seq:position="2">Another thing</ns2:item>
</list>
</document>
';
$sx = simplexml_load_string($xml);
Run Code Online (Sandbox Code Playgroud)
这段代码不起作用 ; 为什么不?
foreach ( $sx->list->ns2:item as $item ) {
echo 'Position: ' . $item['seq:position'] . "\n";
echo 'Item: ' . (string)$item . "\n";
}
Run Code Online (Sandbox Code Playgroud)
第一个问题是->ns2:item语法无效; 但将其更改为此也不起作用:
foreach ( $sx->list->{'ns2:item'} as $item ) { ... }
Run Code Online (Sandbox Code Playgroud)
为什么不呢,你应该用什么呢?
:标记或属性名称中的冒号()表示该元素或属性位于XML命名空间中.命名空间是一种在一个文档中组合不同XML格式/标准的方法,并跟踪哪些名称来自哪种格式.冒号和它之前的部分实际上不是标记/属性名称的一部分,它们只是指示它所在的命名空间.
XML命名空间具有命名空间标识符,该标识符由URI(URL或URN)标识.URI没有指向任何东西,它只是某人"拥有"命名空间的一种方式.例如,SOAP标准使用命名空间http://www.w3.org/2003/05/soap-envelope,OpenDocument文件使用(以及其他)urn:oasis:names:tc:opendocument:xmlns:meta:1.0.问题中的示例使用命名空间http://example.com和https://namespaces.example.org/two.
在文档或文档的一部分中,命名空间被赋予本地前缀,这是您在冒号之前看到的部分.例如,在不同的文件中,SOAP命名空间可能会被给予本地前缀soap:,SOAP:,SOAP-ENV:,env:,或只ns1:.这些名称使用特殊xmlns属性链接回命名空间的标识符,例如xmlns:soap="http://www.w3.org/2003/05/soap-envelope".特定文档中前缀的选择完全是任意的,并且可以在每次生成时改变而不改变含义.
最后,每个文档或文档的一部分都有一个默认命名空间,它是用于没有前缀的元素的命名空间.它由一个xmlns没有的属性定义:,例如xmlns="http://www.w3.org/2003/05/soap-envelope".在上面的示例中,<list>是在默认命名空间中,定义为http://example.com.
有点奇怪的是,未加前缀的属性永远不会出现在默认名称空间中,而是出现在一种"void namespace"中,标准没有明确定义.请参阅:XML命名空间和未加前缀的属性
如果在具有名称空间的SimpleXML对象上使用print_r,var_dump或类似的"转储结构"函数,则不会显示某些内容.它仍然存在,可以按如下所述进行访问.
SimpleXML提供了两种使用命名空间的主要方法:
->children()方法允许您访问特定命名空间中的子元素.它有效地切换对象以查看该命名空间,直到再次调用它来切换回或另一个命名空间.->attributes()方法以类似的方式工作,但允许您访问特定命名空间中的属性.这两种方法都将名称空间标识符作为其第一个参数.由于这些标识符相当长,因此定义一个常量或变量来表示您正在使用的命名空间会很有用,因此您无需在任何地方复制和粘贴完整的URI.
例如,上面的例子可能变成:
define('XMLNS_EG2', 'https://namespaces.example.org/two');
define('XMLNS_SEQ', 'urn:example:sequences');
foreach ( $sx->list->children(XMLNS_EG2)->item as $item ) {
echo 'Position: ' . $item->attributes(XMLNS_SEQ)->position . "\n";
echo 'Item: ' . (string)$item . "\n";
}
Run Code Online (Sandbox Code Playgroud)
作为简写,您还可以通过给出第二个参数来传递方法名称空间的本地别名true.请记住,这可能前缀随时更改,例如,发电机可以分配的前缀ns1,ns2等,并以不同的顺序,如果代码稍有改变它们分配.使用这个简写,代码将变为:
foreach ( $sx->list->children('ns2', true)->item as $item ) {
echo 'Position: ' . $item->attributes('seq', true)->position . "\n";
echo 'Item: ' . (string)$item . "\n";
}
Run Code Online (Sandbox Code Playgroud)
(这个简写是在PHP 5.2中添加的,你可能会看到很老的例子,使用更长篇版本的版本$sx->getNamespaces来获取前缀 - 标识符对的列表.)
| 归档时间: |
|
| 查看次数: |
1419 次 |
| 最近记录: |