我正在用PHP开发一个SOAP客户端,调用一直进行到服务fine,但存在彼此相同元素的调用除外。当这种情况发生时,似乎不是创建两个单独但相同的元素,比如:
<ns1:someelement>
<ns1:name>name1</ns1:name>
<ns1:value>value1</ns1:value>
</ns1:someelement>
<ns1:someelement>
<ns1:name>name1</ns1:name>
<ns1:value>value1</ns1:value>
</ns1:someelement>
它坚持只复制元素的一个副本,并为其分配一个ID,并对该元素的任何后续实例使用href(如下所示),这是我使用的Web服务不支持的(我不知道为什么,但这并不重要,因为我无法更改它)
<ns1:someelement id="#ref1">
<ns1:name>name1</ns1:name>
<ns1:value>value1</ns1:value>
</ns1:someelement>
<ns1:someelement href="#ref1" />
因此,我的问题是如何强制XML完整地包含重复元素,而不是使用hrefs/ids。我在PHP SoapClient的文档中查看了一个选项或类似的东西,但找不到任何东西。如有任何帮助或建议,我们将不胜感激。谢谢
SoapClient只有在多个XML节点上使用同一对象时才会进行引用。如果不需要参照,请为每个位置创建一个新对象。
在您的PHP代码中创建一个具有唯一索引的属性,这样得到的XML将看起来像:
<ns1:someelement>
<ns1:name>name1</ns1:name>
<ns1:value>value1</ns1:value>
<ns1:index>0</ns1:value>
</ns1:someelement>
<ns1:someelement>
<ns1:name>name1</ns1:name>
<ns1:value>value1</ns1:value>
<ns1:index>1</ns1:value>
</ns1:someelement>
然后PHP SoapClient将不会对相同的数据副本进行href引用,在我的情况下,web服务成功地忽略了这些唯一字段。不,我不会在PHP代码中传递与引用相同的someelement字段。它们是被克隆的,但不幸的是,PHP SoapClient足够聪明,可以将它们的多次出现压缩为引用。
- 确保不使用引用
- 尝试使用
SoapParam
手动添加参数 - 尝试使用
SoapVar
手动添加参数
$soapClient->__soapCall('Method', array(
new SoapParam($someelement1, 'someelement'),
// or
new SoapVar('<ns1:someelement><ns1:name>name1</ns1:name><ns1:value>value1</ns1:value></ns1:someelement>', XSD_ANYXML)
));
你好,你可以尝试这个修复程序:
您需要扩展SoapClient并修复生成的请求:
你需要在这里添加导致问题的标签
$tags = ['Tag1', 'Tag2', 'Tag3'];
然后使用MySoapClient而不是SoapClient
class MySoapClient extends SoapClient {
public function __construct($a, $b){
parent::__construct($a, $b);
}
public function __doRequest($request, $location, $action, $version, $one_way = 0) {
$tags = ['Tag1', 'Tag2', 'Tag3'];
foreach($tags as $tag){
if (preg_match("~<ns1:{$tag} id="ref(.+)">(.+)</ns1:{$tag}>~ismU", $request, $matches)) {
$ref = $matches[1];
$request = str_replace([' id="ref'.$ref.'"'], '', $request);
$tagValue = "<ns1:{$tag}>{$matches[2]}</ns1:{$tag}>";
$request = str_replace("<ns1:{$tag} href="#ref{$ref}"/>", $tagValue, $request);
}
}
return parent::__doRequest($request, $location, $action, $version);
}
}