2012-03-16 8 views
5

Sto lavorando su un client SOAP in PHP e le chiamate passano attraverso l'ammenda del servizio, ad eccezione delle chiamate in cui ci sono elementi identici a vicenda. Sembra che quando questo accade, piuttosto che creare due elementi separati ma identici, come questo:PHP SoapClient crea riferimenti XML per elementi identici, lo rende inaccettabile per il servizio

<ns1:someelement> 
    <ns1:name>name1</ns1:name> 
    <ns1:value>value1</ns1:value> 
</ns1:someelement> 
<ns1:someelement> 
    <ns1:name>name1</ns1:name> 
    <ns1:value>value1</ns1:value> 
</ns1:someelement> 

essa insiste sul fare una sola copia dell'elemento e assegnando un ID, e utilizzando href per eventuali successive istanze di tale elemento (vedi sotto), che non è supportata dal webservice sto usando (non so perché questo è, ma non ha molta importanza, perché non posso cambiarlo)

<ns1:someelement id="#ref1"> 
    <ns1:name>name1</ns1:name> 
    <ns1:value>value1</ns1:value> 
</ns1:someelement> 
<ns1:someelement href="#ref1" /> 

Quindi il mio la domanda è come potrei forzare l'XML a uscire con gli elementi duplicati inclusi in pieno, piuttosto che usando hrefs/ids. Ho controllato i documenti per PHP SoapClient per un'opzione o qualcosa del genere, ma non ho trovato nulla. Qualsiasi aiuto o consiglio sarebbe molto apprezzato. Grazie.

+0

Nessuno dei client PHP di soap è così eccezionale. È abbastanza banale distribuirne uno, almeno per un particolare servizio web. Sinceramente raccomanderei di seguire questa strada se quelli preconfezionati non funzionano per te (mi sono trovato di fronte a questo problema più di una volta, il handrolling ha funzionato bene). –

risposta

0
  • fare attenzione a non utilizzare i riferimenti
  • tenta di aggiungere params manualmente con SoapParam
  • tenta di aggiungere params manualmente con SoapVar

$soapClient->__soapCall('Method', array(
    new SoapParam($someelement1, 'someelement'), 
    // or 
    new SoapVar('<ns1:someelement><ns1:name>name1</ns1:name><ns1:value>value1</ns1:value></ns1:someelement>', XSD_ANYXML) 
)); 
0

Nel codice PHP fare una proprietà con un indice univoco, quindi l'XML risultante avrà il seguente aspetto:

<ns1:someelement> 
    <ns1:name>name1</ns1:name> 
    <ns1:value>value1</ns1:value> 
    <ns1:index>0</ns1:value> 
</ns1:someelement> 
<ns1:someelement> 
    <ns1:name>name1</ns1:name> 
    <ns1:value>value1</ns1:value> 
    <ns1:index>1</ns1:value> 
</ns1:someelement> 

Quindi PHP SoapClient non farà riferimento ai riferimenti href alle stesse copie di dati e il servizio Web ha ignorato con successo questi campi univoci nel mio caso. No, non passo gli stessi campi di someelement come riferimento nel codice PHP. Sono clonati, tuttavia PHP SoapClient è abbastanza intelligente da comprimere le loro molteplici occorrenze come riferimenti, sfortunatamente.

0

Ciao Si può provare questa correzione:

È necessario estende la SoapClient e fissare la richiesta generata:

È necessario aggiungere i tag che causano problemi qui

$tags = ['Tag1', 'Tag2', 'Tag3']; 

E quindi utilizzare il MySoapClient anziché SoapClient

class MySoapClient extends SoapClient { 

public function __construct($a, $b){ 
    parent::__construct($a, $b); 
} 

public function __doRequest($request, $location, $action, $version, $one_way = 0) { 

    $tags = ['Tag1', 'Tag2', 'Tag3']; 
    foreach($tags as $tag){ 
     if (preg_match("~<ns1:{$tag} id=\"ref(.+)\">(.+)</ns1:{$tag}>~ismU", $request, $matches)) { 
      $ref = $matches[1]; 

      $request = str_replace([' id="ref'.$ref.'"'], '', $request); 

      $tagValue = "<ns1:{$tag}>{$matches[2]}</ns1:{$tag}>"; 
      $request = str_replace("<ns1:{$tag} href=\"#ref{$ref}\"/>", $tagValue, $request); 
     } 
    } 
    return parent::__doRequest($request, $location, $action, $version); 
} 

}

3

SoapClient crea un riferimento solo quando si utilizza lo stesso oggetto su più nodi XML. Crea per ogni luogo un nuovo oggetto se non vuoi i riferimenti.

Problemi correlati