无法将多维数组从 PHP 序列化为 XML

6 php xml soap soapui laravel

我正在通过 SoapUi 发送 SOAP 请求来测试此 Web 服务。

我目前有这个 PHP 数组:

array(7) {
  ["name"]=>
  string(9) "John Doe"
  ["date"]=>
  string(23) "2021-11-30 00:00:00.000"
  ["job"]=>
  string(31) "developer"
  ["where_from"]=>
  string(15) "france"
  ["address"]=>
  array(3) {
    ["country"]=>
    string(15) "france"
    ["city"]=>
    string(10) "paris"
    ["vat_number"]=>
    string(1) "123456"
  }
  ["items"]=>
  array(1) {
    [0]=>
    array(2) {
      ["cook"]=>
      string(7) "spoon"
      ["clean"]=>
      string(14) "vacuum"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试将其转换为 XML:

function convertToXml($data, $name='root', &$doc=null, &$node=null){
    if ($doc==null){
        $doc = new DOMDocument('1.0','UTF-8');
        $doc->formatOutput = TRUE;
        $node = $doc;
    }

    if (is_array($data)){
        foreach($data as $var=>$val){
            if (is_numeric($var)){
                convertToXml($val, $name, $doc, $node);
            }else{
                if (!isset($child)){
                    $child = $doc->createElement($name);
                    $node->appendChild($child);
                }

                convertToXml($val, $var, $doc, $child);
            }
        }
    }else{
        $child = $doc->createElement($name);
        $node->appendChild($child);
        $textNode = $doc->createTextNode($data);
        $child->appendChild($textNode);
}

    if ($doc==$node) return $doc->saveXML();
}
Run Code Online (Sandbox Code Playgroud)

但是,我在 SOAPUI 中收到以下响应:

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Body>
      <SOAP-ENV:Fault>
         <faultcode xsi:type="xsd:string">SOAP-ENV:Server</faultcode>
         <faultactor xsi:type="xsd:string"/>
         <faultstring xsi:type="xsd:string">unable to serialize result</faultstring>
         <detail xsi:type="xsd:string"/>
      </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)

我尝试过使用较小的数组,它可以工作,但是对于这个数组,它不能按预期工作。

有人可以帮忙吗?

- - - - - - - - - - - - 更新 - - - - - - - - - - - - - --------

我期望得到的回应:

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://ex.pt/soap/WebServices">
   <SOAP-ENV:Body>
      <ns1:Person xmlns:ns1="https://ex.pt/webservices">
         
         <data xsi:type="tns:getPersonInfo">
            <name xsi:type="xsd:string">John</name>
            <surname xsi:type="xsd:string">Doe</surname>
            <job xsi:type="xsd:string">developer</job>
            <from xsi:type="xsd:string">france</from>
            <address xsi:type="tns:getAddress">
               <country xsi:type="xsd:string">france</country>
               <city xsi:type="xsd:string">paris</city>
               <post_code xsi:type="xsd:string">12345</post_code>
            </address>
            <items xsi:type="tns:getItems">
               <item xsi:type="xsd:string">
                  <name xsi:type="xsd:string">pillow</name>
                  <material xsi:type="xsd:string">cotton</material>
               </item>
               .... other items
            </items>
         </data>
      </ns1:Person>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)

它如何检索响应:

<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://ex.pt/soap/WebServices">
       <SOAP-ENV:Body>
          <ns1:Person xmlns:ns1="https://ex.pt/webservices">
             
             <data xsi:type="tns:getPersonInfo">
                <name xsi:type="xsd:string">John</name>
                <surname xsi:type="xsd:string">Doe</surname>
                <job xsi:type="xsd:string">developer</job>
                <from xsi:type="xsd:string">france</from>
                <address xsi:type="tns:getAddress">
                   <country xsi:type="xsd:string">france</country>
                   <city xsi:type="xsd:string">paris</city>
                   <post_code xsi:type="xsd:string">12345</post_code>
                </address>
                <items xsi:type="tns:getItems"/>
             </data>
          </ns1:Person>
       </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)

“items”的 xml 架构

<part name="items" type="tns:getItems"/>


<xsd:complexType name="getItems">
  <xsd:complexContent>
     <xsd:restriction base="SOAP-ENC:Array">
        <xsd:attribute ref="SOAP-ENC:arrayType wsdl:arrayType="tns:ItemInfo[]"/>
     </xsd:restriction>
  </xsd:complexContent>
</xsd:complexType>

<xsd:complexType name="ItemInfo">
   <xsd:all>
     <xsd:element name="name" type="xsd:string"/>
     <xsd:element name="material" type="xsd:string"/>
  </xsd:all>
</xsd:complexType>
    
Run Code Online (Sandbox Code Playgroud)

Joh*_*obo 5

不确定这是一种优雅的方法,但它可能会帮助您获得一些想法来获得您提到的肥皂响应。首先,您必须构建如下所示的数组

$data = [
        'SOAP-ENV:Body' => [
            'ns1:Person' => [
                'info' => [
                    "name" => ['_attributes' => ['xsi:type' => 'xsd:string'], '_value' => "John Doe"],
                    "surname" => ['_attributes' => ['xsi:type' => 'xsd:string'], '_value' => "Doe"],
                    "job" => ['_attributes' => ['xsi:type' => 'xsd:string'], '_value' => "developer"],
                    "from" =>['_attributes' => ['xsi:type' => 'xsd:string'], '_value' =>  "france"],
                    "address" => [
                        "country" => ['_attributes' => ['xsi:type' => 'xsd:string'], '_value' => "france"],
                        "city" => ['_attributes' => ['xsi:type' => 'xsd:string'], '_value' => "paris"],
                        "post_code" => ['_attributes' => ['xsi:type' => 'xsd:string'], '_value' => "123456"],
                        '_attributes' => ['xsi:type' => 'tns:getAddress']
                    ],
                    "items" => [
                        '__custom:item:1' => [
                            "name" => ['_attributes' => ['xsi:type' => 'xsd:string'], '_value' => "spoon"],
                            "material" => ['_attributes' => ['xsi:type' => 'xsd:string'], '_value' => "vacuum"],
                        ],
                        '_attributes' => ['xsi:type' => 'tns:getItems']
                    ],
                    '_attributes' => ['xsi:type' => 'tns:getPersonInfo',]
                ],
                '_attributes' => ['xmlns:ns1' => 'https://ex.pt/webservices',]
            ],
        ]

    ];
Run Code Online (Sandbox Code Playgroud)

使用包array-to-xml参考: https: //github.com/spatie/array-to-xml

    $response = ArrayToXml::convert($data, [
        'rootElementName' => 'SOAP-ENV:Envelope',
        '_attributes' => [
            'SOAP-ENV:encodingStyle' => 'http://schemas.xmlsoap.org/soap/encoding/',
            'xmlns:SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
            'xmlns:xsd' => 'http://www.w3.org/2001/XMLSchema',
            'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
            'xmlns:SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/',
            'xmlns:tns' => 'http://ex.pt/soap/WebServices'
        ],
    ], true, 'UTF-8');
Run Code Online (Sandbox Code Playgroud)