SimpleXML名称空间和属性

时间:2014-04-29 15:05:53

标签: php simplexml

我有一个看起来像这样的xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
    <response>
        <result code="1001">
            <msg>Command completed successfully; action pending</msg>
            <extValue>
            <value xmlns:epp="urn:ietf:params:xml:ns:epp-1.0">
            <epp:undef/>
            </value>
            <reason>200 Command completed successfully</reason>
            </extValue>
        </result>
        <extension>
            <keyvalue:extension xmlns:keyvalue="http://schema.ispapi.net/epp/xml/keyvalue-1.0"
            xsi:schemaLocation="http://schema.ispapi.net/epp/xml/keyvalue-1.0 keyvalue-1.0.xsd">
                <keyvalue:kv key="APPLICATION" value="3725"/>
                <keyvalue:kv key="AUTH" value="ZBh5ralfPl"/>
                <keyvalue:kv key="CLASS" value="APP_EOI"/>
                <keyvalue:kv key="CREATEDBY" value="SYSTEM"/>
                <keyvalue:kv key="CREATEDDATE" value="2012-09-03 09:47:10"/>
                <keyvalue:kv key="DOMAIN" value="example2.app"/>
                <keyvalue:kv key="DOMAINUMLAUT" value="example2.app"/>
                <keyvalue:kv key="PEERUSER" value=""/>
                <keyvalue:kv key="STATUS" value="REQUESTED"/>
                <keyvalue:kv key="UPDATEBY" value="SYSTEM"/>
                <keyvalue:kv key="UPDATEDDATE" value="2012-09-03 09:47:10"/>
                <keyvalue:kv key="USER" value="test.user"/>
            </keyvalue:extension>
        </extension>
        <trID>
        <svTRID>RW-22720-1346665630348630</svTRID>
        </trID>
    </response>
</epp>

我正在尝试迭代keyvalues,直到找到带有APPLICATION键的那个。 这就是我到目前为止所拥有的

$xml = new SimpleXMLElement($response);
$namespaces = $xml->getNamespaces(true);
$nodes = $xml->response->extension->children($namespaces["keyvalue"])->extension->children($namespaces["keyvalue"])->children();
print_r($nodes);

返回

  

SimpleXMLElement对象(       [@attributes] =&gt;排列           (               [key] =&gt;应用               [value] =&gt; 3725           )

     

但我不能在$ nodes或$ nodes [0]上调用attributes()方法,因为它会抛出警告或返回空元素。

你能指导我朝正确的方向发展吗?

由于

1 个答案:

答案 0 :(得分:1)

使用

->children();

最后,即使用默认命名空间,将为您提供零元素的子集合。由于它是空的,SimpleXML内部运行一些优化。再次访问它可能会导致错误:

$nodes->attributes()['value']
  

警告:main():节点不再存在于...

也许最好的方法就是把它留下来并命名你正在寻找的孩子:

$nodes = ... ->extension->children($namespaces["keyvalue"])->kv;

print_r($nodes[1]->attributes()['value']);

给出这个输出:

SimpleXMLElement Object
(
    [0] => ZBh5ralfPl
)

因为它是第二个<kv>元素(从零开始),其属性&#34; value&#34; 被访问。

如果你想将具体元素从中删除,只需将其遗漏(添加->children())。同样的例子:

$nodes = $xml->response->extension->children($namespaces["keyvalue"])->
               extension->children($namespaces["keyvalue"]);

print_r($nodes[1]->attributes()['value']);

这使完全输出相同的内容:

SimpleXMLElement Object
(
    [0] => ZBh5ralfPl
)

因为那里只有<kv>个元素,所以编号不会改变。

希望这有助于揭开一些光芒。也许比这更好的是使用xpath:

$xml->registerXPathNamespace('kv', $namespaces["keyvalue"]);

var_dump($xml->xpath('//kv:kv[@key = "AUTH"]/@value')[0]);

给出了:

class SimpleXMLElement#6 (1) {
  public $@attributes =>
  array(1) {
    'value' =>
    string(10) "ZBh5ralfPl"
  }
}

Xpath专门用于遍历。在名称空间方面,这甚至更好。