PHP SoapClient为相同的元素创建XML引用,使其无法接受服务

时间:2012-03-16 20:59:20

标签: php xml soap

我正在使用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的文档以获取选项或类似的东西,但找不到任何东西。任何帮助或建议将不胜感激。感谢。

4 个答案:

答案 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);
}

}