2009-08-25 20 views
6

Parece que no puedo encontrar la manera de establecer un atributo para una solicitud SOAP sin usar la codificación XSD_ANYXML.Solicitud SOAP con el atributo

El parámetro de la petición debe ser el siguiente

<request 
    xmlns:ns="/some/ns"> 
    ... 
     <ns:parameter attr="some attribute"> 
      value 
     </ns:parameter> 
    ... 
</request> 

Por supuesto funciona el siguiente código, pero es bastante feo (feo, ya que utiliza la concatenación de cadenas donde debe utilizar la API SOAP_Client y porque lo hace no utilice el espacio de nombres en general)

$param = new SoapVar(
    '<ns_xxx:parameter xmlns:ns_xxx="/some/ns" attr="some attribute"> 
     value 
    </ns_xxx:parameter>', 
    XSD_ANYXML 
); 

¿hay una mejor manera de crear un parámetro de la petición SOAP con un espacio de nombres y un atributo?

Estoy buscando el.h. como la siguiente (esto es sólo un pseudo código usando la API SoapVar):

$param = new SoapVar(
    array(
     '_' => 'value', 
     'attr' => 'some attribute' 
    ), 
    SOME_ENCODING, 
    null, 
    null, 
    null, 
    '/some/ns' 
); 
+0

No soy tan versado en SOAP como quiero, pero ¿admite solicitudes con atributos? (Sé que el WSDL tiene atributos, pero ¿cómo maneja los atributos en el XML que se le envía?) ¿Está creando el servicio o ya está configurado? Si es su servicio, soltaría la parte de atributo y la movería a su propio elemento dentro del parámetro. Tal vez como un elemento sin valor, como '' – Anthony

+0

@Anthony: desafortunadamente no controlo el servidor SOAP y no tengo influencia sobre la definición del servicio; (de lo contrario, por supuesto, podría simplemente convertir el atributo en un elemento –

Respuesta

0

de SOAP no soporta atributos, puede ser que usted debe utilizar en su lugar RESTO!

EDIT: Por favor, compruebe el W3C Física: "A 4,3 Jabón" y recuerda que lo necesario para codificar el mensaje con "jabón sobre" espacio de nombres y describir sus tipos XML es por eso, se puede' t usa atributos para describir tus datos de mensaje.

¡Pero si me preguntas, puede ser posible! Puede usar un analizador de SoapClient personalizado o algo así y convertir su mensaje como lo desee. Un ejemplo de eso puede ser RSS sobre SOAP http://www.ibm.com/developerworks/webservices/library/ws-soaprdf. Pero, el problema sería que omitiría la información descriptiva sobre sus datos/tipos de mensajes y otros clientes no podrían entender fácilmente sus mensajes.

Mi mejor práctica para usted sería utilizar elementos en lugar de atributos, , sé que necesita arreglar su esquema XML, pero eso es lo que sucede o cambiar a otra tecnología.

+1

entiendo su gusto de REST sobre SOAP. Sin embargo, esta respuesta realmente no ayuda en absoluto. No ayuda decirle a la gente, no usar una tecnología, cuando intentan resolver un problema en esa tecnología en particular. usted escribe es simplemente incorrecto: SOAP soporta atributos. cf http: //www.w3.org/TR/2000/NOTE-SOAP-20000508/# _ Toc478383492 –

+0

No, prefiero SOAP más REST. Estoy desarrollando con servicios web SOAP y PHP durante un par de años. He modificado un poco mi respuesta, espero que esto ayude. – RedAssBaboon

+0

La respuesta de RAB es técnicamente correcta. El problema es que algunos implementadores requerirán que los datos se pasen en atributos de todos modos. La implementación SoapVar de PHP, por otro lado, sigue la letra de la ley y no ayuda con atributos como lo haría una biblioteca XML normal. – method

-3

SOAP 1 no admite atributos. Aquí está un ejemplo de código Perl usando ambos atributos y valores (de un cliente):

$som = $client->call(
    'tran:getContent', 
    SOAP::Header->name('cred:credentials')->attr({ 
     'username' => $username, 
     'password' => 'xxx', 
     'customerID' => 'xxx'} 
    ), 
    SOAP::Data->name('contentID')->value('9999') 
) 
+2

Lástima que la pregunta era sobre PHP y no Prel. –

3

Para ello, es necesario derivar la clase de SoapClient y anular la __doRequest método():

class ABRSoapClient extends SoapClient { 

    // return xml request 
    function __doRequest($request, $location, $action, $version) { 
     $dom = new DOMDocument('1.0', 'UTF-8'); 
     $dom->preserveWhiteSpace = false; 
     $xml= $dom->loadXML($request); 
     // Goto request Node and Set the attribute 
     $attr_ns = $dom->createAttributeNS('xmlns:ns', ''); // instead of xmlns:ns use Namespace URL 
     $attr_ns->value = '/some/ns'; 
     // add atribute in businessReport node 
     $dom->getElementsByTagName($report_type)->item(0)->appendChild($attr_ns); 
     $request = $dom->saveXML(); 
     return parent::__doRequest($request, $location, $action, $version); 
    } 
} 

$client = new ABRSoapClient(.....); 
$save_result = $client->request($param); 

// You can check the form request using function 
$client->__getLastRequest(); 

Espero que esto resuelva su problema.

+0

No sabía cómo personalizar la función __doRequest, pero tenía esta línea de código y funcionó: // Espacio de nombres sustituto a todos los tipos conocidos $ request = str_replace ('RequestBase', 'ns1: RequestBase ', $ solicitud); padre devuelto :: __ doRequest ($ solicitud, $ ubicación, $ acción, $ versión); –

Cuestiones relacionadas