2015-12-10 10 views
14

sto inviando una chiamata a Canada Post usando il loro WSDL in dotazione che contiene una sezione simile a questo:PHP SoapClient non la manipolazione astratta e substitutionGroup attributi in WSDL

<!-- group-id and transmit-shipment are mutually exclusive --> 
<xsd:element name="groupIdOrTransmitShipment" abstract="true" /> 
<xsd:element name="group-id" type="tns:GroupIDType" substitutionGroup="tns:groupIdOrTransmitShipment"/> 
<xsd:element name="transmit-shipment" type="xsd:boolean" fixed="true" substitutionGroup="tns:groupIdOrTransmitShipment"/> 

<xsd:complexType name="ShipmentType"> 
    <xsd:all> 
     <xsd:element ref="tns:groupIdOrTransmitShipment" /> 
     <xsd:element name="quickship-label-requested" type="xsd:boolean" minOccurs="0"/> 
     <xsd:element name="cpc-pickup-indicator" type="xsd:boolean" fixed="true" minOccurs="0"/> 
     <xsd:element name="requested-shipping-point" type="tns:PostalCodeType" minOccurs="0"/> 
     <xsd:element name="shipping-point-id" type="tns:OutletIDType" minOccurs="0" /> 
     <xsd:element name="expected-mailing-date" type="xsd:date" minOccurs="0"/> 
     <xsd:element name="delivery-spec" type="tns:DeliverySpecType"/> 
     <xsd:element name="return-spec" type="tns:ReturnSpecType" minOccurs="0"/> 
    </xsd:all> 
</xsd:complexType> 

Nel loro esempio di codice che estendono la classe e sapone override del metodo __doRequest() Soap in questo modo:

/* 
Need to override SoapClient because the abstract element 'groupIdOrTransmitShipment' is expected to be in the request in order for validation to pass. 
So, we give it what it expects, but in __doRequest we modify the request by removing the abstract element and add the correct element. 

*/ 

class MySoapClient extends SoapClient { 

    function __construct($wsdl, $options = null) { 
     parent::__construct($wsdl, $options); 
    } 

    function __doRequest($request, $location, $action, $version, $one_way = NULL) { 
     $dom = new DOMDocument('1.0'); 
     $dom->loadXML($request); 
     //get element name and values of group-id or transmit-shipment. 
     $groupIdOrTransmitShipment = $dom->getElementsByTagName("groupIdOrTransmitShipment")->item(0); 
     $element = $groupIdOrTransmitShipment->firstChild->firstChild->nodeValue; 
     $value = $groupIdOrTransmitShipment->firstChild->firstChild->nextSibling->firstChild->nodeValue; 

     //remove bad element 
     $newDom = $groupIdOrTransmitShipment->parentNode->removeChild($groupIdOrTransmitShipment); 

     //append correct element with namespace 
     $body = $dom->getElementsByTagName("shipment")->item(0); 
     $newElement = $dom->createElement($element, $value); 
     $body->appendChild($newElement); 

     //save $dom to string 
     $request = $dom->saveXML(); 
     //echo $request; 

     //doRequest 
     return parent::__doRequest($request, $location, $action, $version); 
    } 
} 

Usando il loro metodo overidden funziona bene in quanto altera la richiesta XML, ma è assolutamente confuso per me perché lo stanno facendo. C'è qualcosa di fondamentalmente sbagliato nel WSDL? Si tratta di un bug in PHP SoapClient? Mi piacerebbe un modo per inviare una richiesta valida senza sovrascrivere i metodi della classe base.

Secondo la mia comprensione, l'autore vuole sia un group-idotransmit-shipment elemento, ma non entrambi o nessuno. Poiché non è possibile avere un elemento <choice> all'interno di un elemento <all>, in base a this discussion on w3c.org, è opportuno dichiarare un gruppo di sostituzione per questo scopo e includere solo uno dei due elementi nella mia richiesta, ma se includo solo transmit-shipment e ometto l'elemento astratto groupIdOrTransmitShipment PHP restituisce un errore:

SOAP-ERROR: Encoding: object has no 'groupIdOrTransmitShipment' property 

UPDATE: Questo è molto vecchio ma potrebbe essere rilevante? https://bugs.php.net/bug.php?id=48570

risposta

1

Ho dovuto sovrascrivere ed estendere anche php SoapClass. Aveva a che fare con php soapclass che si aspettava un determinato formato nella richiesta/risposta, quindi ciò che veniva ricevuto/inviato. L'estensione mi ha permesso di gestire me stesso la formattazione.

Non c'è niente di sbagliato in wsdl, l'errore fa parte della classe. Non c'è modo di aggirare l'override

+0

Sì, l'ho già chiarito nella mia domanda. Anche se il tuo feedback è benvenuto, questa non è una risposta. Dovresti aggiungerlo come commento se desideri. – billynoah

+0

La tua domanda non è chiara allora. Suoni se vuoi una conferma e una spiegazione. Questo è quello che ho dato. –

+0

* "C'è qualcosa di fondamentalmente sbagliato nel WSDL? È un bug in PHP SoapClient? Mi piacerebbe un modo per inviare una richiesta valida senza sovrascrivere i metodi della classe base." * – billynoah

Problemi correlati