PHP SoapClient删除名称的元素

Ric*_*ing 5 php soap-client

我有一个WSDL,它有一个需要属性的元素:

<xsd:complexType name="claim">
  <xsd:annotation>
    <xsd:documentation>Claim Element</xsd:documentation>
  </xsd:annotation>
  <xsd:sequence>
    <!-- other elements removed -->
  </xsd:sequence>
  <xsd:attribute name="claimId" type="xsd:nonNegativeInteger" use="required" />
</xsd:complexType>
Run Code Online (Sandbox Code Playgroud)

就生成的xml而言,它应该如下所示:

<claims>
    <claim claimId="1">
        <!-- elements removed -->
    </claim>
    <!-- more claims -->
</claims>
Run Code Online (Sandbox Code Playgroud)

在一个foreach循环中,我将一个元素数组放在一起,并使用该属性作为键的一部分:

//$claim = array of key/value pairs
$claim = [...];
$claim = new \SoapVar($claim, SOAP_ENC_OBJECT, null, null, 'claim claimId="' . ($key+1) . '"');
$claims['claim claimId="'.($key+1).'"'] = $claim;
Run Code Online (Sandbox Code Playgroud)

当将它传递给SoapClient时,元素将被删除:

//$client = new \SoapClient($wsdl);
$client->checkClaims($claims);
Run Code Online (Sandbox Code Playgroud)

但我得到的只是:

<claims />
Run Code Online (Sandbox Code Playgroud)

如何让我的soap客户端claim在soap调用中正确解析元素?

Ric*_*ing 0

知道\SoapClient可以接受 xml 字符串,我决定将数据数组转换为 xml 字符串:

/**
 * Convert an array to an xml. Recursive function.
 * @param array $array
 * @param String $rootElement OPTIONAL name of root element.
 * @param \Simple XMLElement $xml OPTIONAL
 * @return String
 */
function arrayToXml($array, $rootElement = null, $xml = null) {
    $_xml = $xml;

    if ($_xml === null) {
        $_xml = new \SimpleXMLElement($rootElement !== null ? $rootElement : '<root/>');
    }

    foreach ($array as $k => $v) {
        if (is_array($v)) { //nested array
            arrayToXml($v, $k, $_xml->addChild($k));
      } else {
            $_xml->addChild($k, $v);
      }
    }
    //Remove xml doctype and root name spaces.
    return str_replace(["<?xml version=\"1.0\"?>\n", '<root>', "</root>\n"], '', $_xml->asXML());
}

//my array of claims
$claims = [
    'claim claimId="1"' => [
        //...
    ],
    'claim claimId="2"' => [
        //...
    ],
    //...
];
$claims = arrayToXml($claims);
Run Code Online (Sandbox Code Playgroud)

这会生成一个 xml 字符串:

<claim claimId="1"><!-- stuff --></claim claimId="1"><claim claimId="2"><!-- stuff --></claim claimId="2">
Run Code Online (Sandbox Code Playgroud)

下一步是从结束标签中删除该属性:

$claims = preg_replace('#</claim claimId="\d+">#', '</claim>', $claims);
Run Code Online (Sandbox Code Playgroud)

最后,我将 xml 包装在适当的参数名称中并将其转换为 a \SoapVar,以便\SoapClient正确解析它:

$claims = '<ns1:claims>' . $claims . '</ns1:claims>';
$claims = new \SoapVar($claims, XSD_ANYXML, 'http://www.w3.org/2001/XMLSchema-instance');
Run Code Online (Sandbox Code Playgroud)

传递$claims到 my\SoapClient并运行var_dump($client->__getLastRequest());将我生成的 xml 显示为:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.w3.org/2001/XMLSchema-instance"><SOAP-ENV:Body><ns1:claims><claim claimId="1"><!--stuff--></claim><claim claimId="2"><!--stuff--></claim></ns1:claims></SOAP-ENV:Body></SOAP-ENV:Envelope>
Run Code Online (Sandbox Code Playgroud)

正如它所希望的那样。