LefterisL
LefterisL

Reputation: 1143

Parse element from nested namespaces XML in PHP

What I have so far is the code below. I think the issue is in the $bodies = $xml->xpath('domain:cd');, I don't know exactly how to define the path.

Tried viewing some examples but didnt manage to figure it out.

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="1000">
    <msg>Command completed successfully</msg>
    </result>
<resData>
    <domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"
    xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0
    domain-1.0.xsd">
        <domain:cd>
        <domain:name avail="0">domain001.gr</domain:name>
        <domain:reason>In Use.</domain:reason></domain:cd>
    </domain:chkData>
</resData>

PHP code

$xml = simplexml_load_string($result, NULL, NULL, 'urn:ietf:params:xml:ns:epp-1.0');
$xml->registerXPathNamespace('domain', 'urn:ietf:params:xml:ns:domain-1.0');

$bodies = $xml->xpath('/resData/domain:chkData');
echo "alitheia";
foreach($bodies as $body){

    $reply = $body->children('domain', TRUE)->cd;

    $nameout =(string)$reply->name;
    echo $nameout;
    echo "alitheia2";

}

The "alitheia" echos are for debugging to see where my code reaches. "Alitheia2" never shows up.

CODE THAT SOVLED IT IN CASE SOMEONE ELSE COMES UP WITH THIS ISSUE

//i loaded the xml in the p2xml variable using file_get_contents
        $p2xml = new SimpleXmlElement($p2xmlf);
        foreach ($p2xml->response->resData $entry2)
        {
            $namespaces = $entry2->getNameSpaces(true);
            $dc = $entry2->children($namespaces['domain']);
            $nameout = $dc->chkData->name;
            //below is what i used to get the attribute
                            $attrout = $dc->chkData->name->attributes();
            $oxml = $p2xml->asXML();
        }

Upvotes: 1

Views: 563

Answers (2)

hakre
hakre

Reputation: 197767

You did pretty well, the only thing that mismatches is the path to element:

/resData/domain:chkData

This is your path, it implies that <resData> would be a child element of the root (document) element. But it's not, it is a child of <response>> that itself is a child of the root element:

/response/resData/domain:chkData'
#########

With this little change your code just works.

Upvotes: 0

Jens Erat
Jens Erat

Reputation: 38682

Two problems with your code:

  1. Also register and use the urn:ietf:params:xml:ns:epp-1.0 namespace:

    $xml->registerXPathNamespace('epp', 'urn:ietf:params:xml:ns:epp-1.0');
    

    and use it in your XPath expression: epp:resData instead of resData.

  2. There is no <resData/> root element. If you want to find all of them, use //epp:resData/domain:chkData, or provide the full path: /epp:epp/epp:response/epp:resData/domain:chkData.


If you only need the name, why not directly select it using XPath?

$bodies = $xml->xpath('//epp:resData/domain:chkData/domain:cd/domain:name/text()');
// Or even use: '//domain:name/text()'
foreach ($bodies as $body)
  echo $body;

Upvotes: 1

Related Questions