parse an XML with SimpleXML which has multiple namespaces

38,885

Solution 1

I think you need to register the namespacing and access with XPath. Something like the following should get you going (I haven't the facility to test this).

$xml = simplexml_load_string($res, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
$xml->registerXPathNamespace('soap-env', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('eb', 'http://www.ebxml.org/namespaces/messageHeader');
$xml->registerXPathNamespace('wsse', 'http://schemas.xmlsoap.org/ws/2002/12/secext');

Then you can do something like:

foreach($xml->xpath('//eb:MessageHeader') as $header)
{
    var_export($header->xpath('//eb:CPAId')); // Should output 'something'.
}

You may not need to register the namespacing, thinking about it, as they are alredy present in the XML. Not sure on this though, would need to test.

Hope this helps.

Solution 2

1) Do not use print_r and friends to see what is "in" a SimpleXML object. See https://github.com/IMSoP/simplexml_debug for explanation and alternatives.

2) Namespace support in SimpleXML is provided by the ->children() and ->attributes() methods.

For example you could get the PartyId of the From node like this:

$from_party = (string)$xml->children('soap-env', true)->Header->children('eb', true)->MessageHeader->From->PartyId;
Share:
38,885
perrohunter
Author by

perrohunter

Updated on May 08, 2020

Comments

  • perrohunter
    perrohunter about 4 years

    I have this ugly XML which has alot of namespaces on it, when I try to load it with simpleXML if i indicate the first namespace I'd get an xml object ,but following tags with other namespaces would not make it to the object.

    How can I parse this XML ?

    <?xml version="1.0" encoding="UTF-8"?>
    <soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
        <soap-env:Header>
            <eb:MessageHeader xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" eb:version="1.0" soap-env:mustUnderstand="1">
                <eb:From>
                    <eb:PartyId eb:type="URI">wscompany.com</eb:PartyId>
                </eb:From>
                <eb:To>
                    <eb:PartyId eb:type="URI">mysite.com</eb:PartyId>
                </eb:To>
                <eb:CPAId>something</eb:CPAId>
                <eb:ConversationId>moredata.com</eb:ConversationId>
                <eb:Service eb:type="compXML">theservice</eb:Service>
                <eb:Action>theaction</eb:Action>
                <eb:MessageData>
                    <eb:MessageId>a certain messageid</eb:MessageId>
                    <eb:Timestamp>2009-04-11T18:43:58</eb:Timestamp>
                    <eb:RefToMessageId>mid:areference</eb:RefToMessageId>
                </eb:MessageData>
            </eb:MessageHeader>
            <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext">
                <wsse:BinarySecurityToken valueType="String" EncodingType="wsse:Base64Binary">an impresive binary security toekn</wsse:BinarySecurityToken>
            </wsse:Security>
        </soap-env:Header>
        <soap-env:Body>
            <SessionCreateRS xmlns="http://www.opentravel.org/OTA/2002/11" version="1" status="Approved">
                <ConversationId>the goodbye token</ConversationId>
            </SessionCreateRS>
        </soap-env:Body>
    </soap-env:Envelope>
    

    im trying to parse it with the following code

    <?php
    $xml = simplexml_load_string($res,NULL,NULL,"http://schemas.xmlsoap.org/soap/envelope/");
    ?>
    

    but the $xml object would only contain the following

    SimpleXMLElement Object
    (
        [Header] => SimpleXMLElement Object
            (
            )
    
        [Body] => SimpleXMLElement Object
            (
            )
    
    )