Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

Tengo esta fea XML que tiene una gran cantidad de espacios de nombres en él, cuando intento cargarlo con simplexml si indico el primer espacio de nombres que tendría un objeto XML, pero a raíz de las etiquetas con otros espacios de nombres no lo haría a la objeto.

¿Cómo puedo analizar este 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 tratando de analizarlo con el siguiente código

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

pero el objeto $ xml sólo contendrá la siguiente

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

    [Body] => SimpleXMLElement Object
        (
        )

)
¿Fue útil?

Solución

Creo que es necesario para registrar el namespacing y acceso con XPath. Algo parecido a lo siguiente debería conseguir que ir (no tengo la facilidad para probar esto).

$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');

A continuación, puede hacer algo como:

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

Es posible que no necesita registrar el namespacing, pensando en ello, ya que son todavia presente en el XML. No está seguro de esto, sin embargo, tendría que probar.

Espero que esto ayude.

Otros consejos

1) No utilice amigos print_r y para ver lo que está "en" un objeto SimpleXML. Ver https://github.com/IMSoP/simplexml_debug para la explicación y alternativas.

2) de soporte de espacio de nombres en SimpleXML es proporcionada por el ->children() y ->attributes() métodos.

Por ejemplo, usted podría obtener el PartyId del nodo A partir de la siguiente manera:

$from_party = (string)$xml->children('soap-env', true)->Header->children('eb', true)->MessageHeader->From->PartyId;

Esto es un jabón-sobre. Es posible que desee utilizar un jabón-cliente para abstraer de todo el xml-análisis de distancia. PHP viene con un buen jabón y no-cliente incluido por defecto.

Para cualquier otra cosa que viene a través de este Me rasqué la cabeza tratando de devolver los datos correctos y aunque la respuesta más común fue extremadamente cerca todavía me tomó un tiempo para encontrar la respuesta. Con el tiempo utilizado para ayudar a esta página: https://www.w3schools.com/php/func_simplexml_registerxpathnamespace.asp

Creo que el bucle se puede acceder directamente a lo que necesita. es decir.

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

Probar

   $soap_url = 'http://path/wsdl/somefile.wsdl';
   $soap_client = new SoapClient($soap_url);

   var_dump($soap_client->__getFunctions());

Para más detalle leer aquí

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top