سؤال

I have an xml that looks like this:

<?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>

I am trying to iterate through keyvalues until I find the one with the key of APPLICATION. This is what I have so far

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

That returns

SimpleXMLElement Object ( [@attributes] => Array ( [key] => APPLICATION [value] => 3725 )

)

But I cannot call attributes() method on $nodes or $nodes[0] as it either throws a warning or returns empty element.

Could you please guide me in the right direction?

Thanks

هل كانت مفيدة؟

المحلول

Using

->children();

at the end, that is with the default namespace, will give you a child-collection of zero elements. As it's empty, SimpleXML internally runs some optimizations. Accessing it again might lead to errors:

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

Warning: main(): Node no longer exists in ...

Perhaps the best way is to just leave it out and name the children you're looking for:

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

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

Gives this output:

SimpleXMLElement Object
(
    [0] => ZBh5ralfPl
)

As it's the second <kv> element (zero-based) of which the attribute "value" is accessed.

If you want to leave the concrete element out of it, just leave it out (do not add ->children()). The same example:

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

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

This gives exactly the same output:

SimpleXMLElement Object
(
    [0] => ZBh5ralfPl
)

as there are only <kv> elements as children there, so the numbering does not change.

Hope this helps to shed some light. Perhaps better than all this is to use xpath:

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

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

Which gives:

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

Xpath is specialized on traversal. This is even better when it comes to namespaces.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top