我正在使用PHP中的SOAP客户端,并且调用正在完成服务,除了调用的元素彼此相同。似乎在发生这种情况时,而不是创建两个独立但相同的元素,如下所示:
<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的文档以获取选项或类似的东西,但找不到任何东西。任何帮助或建议将不胜感激。感谢。
答案 0 :(得分:3)
只有在多个XML节点上使用相同的对象时,SoapClient才会生成引用。如果您不想要参考,请为每个地点制作一个新对象。
答案 1 :(得分:0)
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)
));
答案 2 :(得分:0)
在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非常智能,可以将它们的多个出现物作为参考进行压缩。
答案 3 :(得分:0)
您好,您可以尝试此修复:
您需要扩展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);
}
}