2012-09-05 71 views
1

我想調用Web服務,該服務也在開發中,並且在WSDL中定義了一個函數PlaceInvoiceFromStream。函數定義了一個要傳遞的參數,發票。 WSDL導入在XSD shema中定義的類型。如何使用PHP中的本地SoapClient進行SOAP調用?

WSDL看起來是這樣的:

<?xml version="1.0" encoding="utf-8"?> 
<definitions name ="inService" 
    xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:xsdl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
    xmlns:tns="http://localhost/ebiz/ws/" 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    targetNamespace="http://localhost/ebiz/ws/"> 
    <import namespace="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
     location="http://localhost/ebiz/ws/Invoice.xsd" 
    /> 
    <message name="getPlaceInvoiceInput"> 
     <part name="body" element="xsdl:Invoice"/> 
    </message> 
    <message name="getPlaceInvoiceOutput"> 
     <part name="body" type="xsd:string"/> 
    </message> 
    <portType name="inServicePortType"> 
     <operation name="PlaceInvoiceFromStream"> 
      <input message="tns:getPlaceInvoiceInput"/> 
      <output message="tns:getPlaceInvoiceOutput"/> 
     </operation> 
    </portType> 
    <binding name="inServiceBinding" type="tns:inServicePortType"> 
     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> 
     <operation name="PlaceInvoiceFromStream"> 
      <soap:operation soapAction="PlaceInvoiceFromStream"/> 
      <input> 
       <soap:body use="literal"/> 
      </input> 
      <output> 
       <soap:body use="literal"/> 
      </output> 
     </operation> 
    </binding> 
    <service name="inService"> 
     <port name="inServicePort" binding="tns:inServiceBinding"> 
      <soap:address location="http://localhost/ebiz/ws/soapServer.php"/> 
     </port> 
    </service> 
</definitions> 

模式是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<xsd:schema xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDataTypes-2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:udt="urn:oasis:names:specification:ubl:schema:xsd:UnqualifiedDataTypes-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" targetNamespace="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.1"> 
<xsd:import namespace="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" schemaLocation="../common/UBL-CommonAggregateComponents-2.1.xsd"/> 
<xsd:import namespace="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" schemaLocation="../common/UBL-CommonBasicComponents-2.1.xsd"/> 
<xsd:import namespace="urn:oasis:names:specification:ubl:schema:xsd:UnqualifiedDataTypes-2" schemaLocation="../common/UBL-UnqualifiedDataTypes-2.1.xsd"/> 
<xsd:import namespace="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" schemaLocation="../common/UBL-CommonExtensionComponents-2.1.xsd"/> 
<xsd:import namespace="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDataTypes-2" schemaLocation="../common/UBL-QualifiedDataTypes-2.1.xsd"/> 
<xsd:element name="Invoice" type="InvoiceType"/> 
<xsd:complexType name="InvoiceType"> 
    <xsd:sequence> 
     <xsd:element ref="ext:UBLExtensions"/> 
     <xsd:element ref="cbc:UBLVersionID"/> 
     <xsd:element ref="cbc:CustomizationID" minOccurs="0"/> 
     <xsd:element ref="cbc:ProfileID" minOccurs="0"/> 
     <xsd:element ref="cbc:ID"></xsd:element> 
     <xsd:element ref="cbc:CopyIndicator" minOccurs="0"/> 
     <xsd:element ref="cbc:IssueDate"/> 
     <xsd:element ref="cbc:InvoiceTypeCode" minOccurs="0"/> 
     <xsd:element ref="cbc:Note" minOccurs="0"/> 
     <xsd:element ref="cbc:TaxPointDate" minOccurs="0"/> 
     <xsd:element ref="cbc:DocumentCurrencyCode" minOccurs="0"/> 
     <xsd:element ref="cbc:AccountingCost" minOccurs="0"/> 
     <xsd:element ref="cbc:LineCountNumeric" minOccurs="0"/> 
     <xsd:element ref="cac:InvoicePeriod" minOccurs="0"/> 
     <xsd:element ref="cac:OrderReference" minOccurs="0"/> 
     <xsd:element ref="cac:DespatchDocumentReference" minOccurs="0"/> 
     <xsd:element ref="cac:ReceiptDocumentReference" minOccurs="0"/> 
     <xsd:element ref="cac:ContractDocumentReference" minOccurs="0"/> 
     <xsd:element ref="cac:AdditionalDocumentReference" minOccurs="0" maxOccurs="unbounded"/> 
     <xsd:element ref="cac:Signature" minOccurs="0"/> 
     <xsd:element ref="cac:AccountingSupplierParty"/> 
     <xsd:element ref="cac:AccountingCustomerParty"/> 
     <xsd:element ref="cac:BuyerCustomerParty" minOccurs="0"/> 
     <xsd:element ref="cac:SellerSupplierParty" minOccurs="0"/> 
     <xsd:element ref="cac:TaxRepresentativeParty" minOccurs="0"/> 
     <xsd:element ref="cac:Delivery" minOccurs="0" maxOccurs="unbounded"/> 
     <xsd:element ref="cac:DeliveryTerms" minOccurs="0"/> 
     <xsd:element ref="cac:PaymentMeans" maxOccurs="unbounded"/> 
     <xsd:element ref="cac:PaymentTerms" minOccurs="0" maxOccurs="unbounded"/> 
     <xsd:element ref="cac:PrepaidPayment" minOccurs="0" maxOccurs="unbounded"/> 
     <xsd:element ref="cac:AllowanceCharge" minOccurs="0" maxOccurs="unbounded"/> 
     <xsd:element ref="cac:TaxTotal" maxOccurs="unbounded"/> 
     <xsd:element ref="cac:LegalMonetaryTotal"/> 
     <xsd:element ref="cac:InvoiceLine" maxOccurs="unbounded"/> 
    </xsd:sequence> 
</xsd:complexType> 

UBL 2.1架構:http://docs.oasis-open.org/ubl/prd2-UBL-2.1/UBL-2.1.html#SCHEMAS

發票是複雜的數據,保存在XML文件,其中包含名稱空間和屬性。它開始是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<Invoice 
xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" 
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" 
xmlns:sac="urn:oasis:names:specification:ubl:schema:xsd:SignatureAggregateComponents-2" 
xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://localhost/ebiz/ws/Invoice.xsd" 
xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" 
xmlns:sig="urn:oasis:names:specification:ubl:schema:xsd:CommonSignatureComponents-2"> 
    <ext:UBLExtensions> 
     <ext:UBLExtension> 
      <cbc:ID>INVOICE1</cbc:ID> 
      <cbc:Name>InvoiceIssuePlaceData</cbc:Name> 
      <ext:ExtensionAgencyURI>urn:invoice:issueplace</ext:ExtensionAgencyURI> 
      <ext:ExtensionContent> 
       <ext:InvoiceIssuePlace>MyCity</ext:InvoiceIssuePlace> 
      </ext:ExtensionContent> 
     </ext:UBLExtension> 
    </ext:UBLExtensions> 
    <cbc:UBLVersionID>2.1</cbc:UBLVersionID> 
    <cbc:ID>01 1206-2406-568</cbc:ID>` 

等等

我已經試過這種方法:

// LOAD XML and TRANSFORM FOR SoapClient 
$xmlfile = "Invoice123.xml"; 
$xslfile = "xsltForSoapClientRequest.xsl"; 
$xmlDOM = new DOMDocument(); 
$xmlDOM->load($xmlfile); 
$xslDOM = new DOMDocument(); 
$xslDOM->load($xslfile); 
$proc = new XSLTProcessor; 
$proc->importStyleSheet($xslDOM); 
$transformedXML = $proc->transformToDoc($xmlDOM); 
$xmldoc = simplexml_load_string($transformedXML); 

// CREATE ARRAY 
$xmlarr = xml2array($xmldoc->asXML()); 

$client = new SoapClient($wsdl,array('trace'=>1)); 
$result=$client->PlaceInvoiceFromStream($xmlarr); 

,但沒有成功。

XSL變換的變化是:

  • 節點屬性變爲節點元件
  • 複雜節點值變爲 「_」 元件

xml2array變化是:

  • 屬性變得分開陣列

所以,$ xmlarr被髮送到Web服務功能在以下形式:

array(2) { 
    ["Invoice"]=> 
    array(15) { 
    ["ext:UBLExtensions"]=> 
    array(1) { 
     ["ext:UBLExtension"]=> 
     array(4) { 
     ["cbc:ID"]=> 
     string(10) "INVOICE1" 
     ["cbc:Name"]=> 
     string(21) "InvoiceIssuePlaceData" 
     ["ext:ExtensionAgencyURI"]=> 
     string(25) "urn:invoice:issueplace" 
     ["ext:ExtensionContent"]=> 
     array(1) { 
      ["ext:InvoiceIssuePlace"]=> 
      string(7) "MyCity" 
     } 
     } 
    } 
    ["cbc:UBLVersionID"]=> 
    string(3) "2.1" 
    ["cbc:ID"]=> 
    string(16) "01 1206-2406-568" 
... 

    ["Invoice_attr"]=> 
    array(8) { 
    ["xmlns"]=> 
    string(54) "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" 
    ["xmlns:xsi"]=> 
    string(41) "http://www.w3.org/2001/XMLSchema-instance" 
    ["xmlns:cac"]=> 
    string(72) "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" 
    ["xmlns:cbc"]=> 
    string(68) "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" 
    ["xmlns:sac"]=> 
    string(75) "urn:oasis:names:specification:ubl:schema:xsd:SignatureAggregateComponents-2" 
    ["xmlns:ext"]=> 
    string(72) "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" 
    ["xmlns:sig"]=> 
    string(72) "urn:oasis:names:specification:ubl:schema:xsd:CommonSignatureComponents-2" 
    ["xsi:schemaLocation"]=> 
    string(93) "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 http://localhost/ebiz/ws/Invoice.xsd" 
    } 
} 

Web服務調用的結果是:

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

應該是什麼形式正確的SOAP請求?對於SOAP請求,陣列需要什麼樣的形式? SOAP是否基於WSDL和XSD理解「_」元素?或單獨數組中的屬性?

預先感謝在解決這個問題的任何幫助...

UPDATE:

改變WSDL:

<message name="getPlaceInvoiceInput"> 
    <part name="Invoice" element="xsdl:InvoiceType"/> 

SoapClient的接受以下要求:

$xmlarr = array(
    "UBLExtensions"=> 
    array(
     "UBLExtension"=> 
     array(
     "ID"=>"INVOICE1", 
     "Name"=>"InvoiceIssuePlaceData", 
     "ExtensionAgencyURI"=>"urn:invoice:issueplace", 
     "ExtensionContent"=> 
     array(
      "InvoiceIssuePlace"=>"MyCity" 
     ) 
    ) 
    ), 
    "UBLVersionID"=>"2.1", 
    "ID"=>"01 1206-2406-568", 
    ... 

這不是我想要的。我需要在鍵中的命名空間。爲了使SoapClient能夠接受請求數組中的鍵中的名稱空間,例如「ext:UBLExtensions」,應該更改/添加什麼?

+0

您可以添加WSDL和模式嗎?這可能比示例XML消息更有幫助。 – davidfmatheson

+0

添加了WSDL和架構... –

回答

1

我相信你需要在UBLExtensions級別開始你的array級別,而不是Invoice級別。它把你的頂級元素作爲Invoice它預計UBLExtensions和抱怨,當它沒有找到它:

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

它不需要第二Invoice_attr數組,數組元素的名稱去由元素名稱架構,而不是ref值。看你的模式中的ref指向什麼(你似乎沒有列出它),element應該有一個name

+0

Tnx爲您的答案。是的,你在UBLExtensions級別的數組開始是正確的。我也改變了wsdl。現在我沒有錯誤消息,但SoapClient需要使用沒有命名空間的鍵的數組,而我的xml文件包含帶有命名空間的鍵。爲了使SoapClient能夠接受請求數組中的鍵中的名稱空間,例如「ext:UBLExtensions」,應該更改/添加什麼? –

+0

我認爲SoapClient會在構建請求時添加命名空間。你從XML開始,這是不尋常的。 SoapClient旨在允許您從一個數組開始並將其序列化爲一個SOAP請求。檢查請求是否發送(通過WireShark或'__getLastRequest'),您應該看到命名空間。 – davidfmatheson

相關問題