【问题标题】:Issue with sending SOAP request, through soapclient, to service that expects CDATA通过soapclient向需要CDATA的服务发送SOAP请求的问题
【发布时间】:2021-01-23 05:52:26
【问题描述】:

我正在尝试向期望 CDATA 作为请求一部分的服务发出 SOAP 请求。我设法使用 Insomnia 成功地拨打了以下两种方法中的任何一种:

    <ExecuteRequest xmlns="<url>">
      <TAG1>
            <![CDATA[
            <TAG2>
            <TAG3>TEXT1</TAG3>
            <TAG4>TEXT2</TAG3>
            <TAG5>TEXT3</TAG5>
            </TAG2>
                    ]]>
    </TAG1>
    </ExecuteRequest>

    <ExecuteRequest xmlns="<url>">
      <TAG1>
            &lt;TAG2&gt;
            &lt;TAG3&gt;TEXT1&lt;/TAG3&gt;
            &lt;TAG4&gt;TEXT2&lt;/TAG4&gt;
            &lt;TAG5&gt;TEXT3&lt;/TAG5&gt;
            &lt;/TAG2&gt;
    </TAG1>
    </ExecuteRequest>

但我在翻译上述内容以使用 php soapclient 时遇到了麻烦。例如使用以下内容:

  $soapclient = new SoapClient('url?wsdl', array('trace' => 1));
            $xmlWriter = new \XMLWriter();
            $xmlWriter->openMemory(); 
        
            $xmlWriter->startElement('TAG1');
                $xmlWriter->startElement('TAG2');

                $xmlWriter->writeElement('TAG3','TEXT1');
                $xmlWriter->writeElement('TAG4','TEXT2');
                $xmlWriter->writeElement('TAG5','TEXT3');
                
                $xmlWriter->endElement();
            $xmlWriter->endElement();


            $myXml = $xmlWriter->outputMemory(true);

            $params = array(
                new \SoapParam(new \SoapVar($myXml, XSD_ANYXML), 'param')
            );

            $response = $soapclient->__soapCall('ExecuteRequest',$params);

            $lastrequest = $soapclient->__getLastRequest();   

$soapclient->__getLastRequest() 给了我这个输出,这显然不是我想要的,没有 CDATA:

<TAG1>
    <TAG2>
        <TAG3>TEXT1</TAG3>
        <TAG4>TEXT2</TAG4>
        <TAG5>TEXT3</TAG5>
    </TAG2>
</TAG1>

如果我在 xmlwriter 中使用它来手动编写 CDATA:


$xmlWriter->writeCdata('<TAG2>
<TAG3>TEXT1</TAG3>
<TAG4>TEXT2</TAG4>
<TAG5>TEXT3</TAG5>
</TAG2>');

然后由于一些奇怪的原因 $soapclient->__getLastRequest() 返回注释掉的 CDATA 部分,我不知道为什么会这样:


<TAG1>
<!--[CDATA[<TAG2-->
<TAG3>TEXT1</TAG3>
<TAG4>TEXT2</TAG4>
<TAG5>TEXT3</TAG5>
""]]>"
</TAG1>

请注意 TAG2 的结束标签是如何丢失的。

编辑

如果我不使用 xml 写入程序,则会发生与 CDATA 被注释掉的相同问题。

$wholeTag = new \SoapVar("<TAG1><![CDATA[{$text}]]></TAG1>", XSD_ANYXML);
$params = [
  'param' => $wholeTag,
];

有什么想法吗?我很可能以错误的方式处理这个问题,所以我愿意接受任何建议。

【问题讨论】:

  • 有些保留字符不能在 CDATA 中使用,除非将其注释掉,例如 &lt;&amp;'"。也许writeCdata() 会在这些情况发生时自动将数据取出?您是否真的使用了示例中的数据,或者这只是这个问题的一个示例?
  • 是的,数据是真实的,只是将名称更改为更通用。
  • 如果
  • 我同意只注释掉第一行是没有意义的。可能是那种方法,但我不确定,这就是我使用评论而不是答案的原因。
  • 编辑了 OP 以添加发生相同问题的另一个场景。

标签: php soap-client cdata


【解决方案1】:

在这件事上浪费了几个小时后,我最终完全放弃了使用 soapclient 并用 Guzzle 解决了它。

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException; 


$xml = new \SimpleXMLElement("<put the whole xml body here, using the Webservice's SOAP 1.1 sample as a reference>");             
 
$xmlstring = $xml->asXML();


$client = new Client();
        $url = "< the **full** webservice url (used the Webservice's SOAP 1.1 sample as reference)>";
        $action = "action url (used the Webservice's SOAP 1.1 sample as reference)";

   try {
            $response = $client->post($url, 
            ['headers' => 
                ['SOAPAction' => $action,
                'Content-Type' => 'text/xml; charset=utf-8',
                'Host' => "<host url (used the Webservice's SOAP 1.1 sample as reference)>"
                ],
            'body' => $xmlstring
            ]);
    }
    catch (GuzzleException $e) 
    {
        return [ 'status' => $e->getResponse()->getStatusCode(), 'message' => $e->getResponse()->getReasonPhrase()];          
    }
    
    if ($response->getStatusCode() === 200) {
        // Success!
        return $response->getBody();
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-29
    • 2018-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多