我有一个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调用中正确解析元素?
知道\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)
正如它所希望的那样。
| 归档时间: |
|
| 查看次数: |
818 次 |
| 最近记录: |