我正在设置一个 SOAP Web 服务,它应该返回一个复合消息。
此消息的有效实例如下:
<dl190Response xmlns="http://pse/">
<cdhead cisprik="5563167"/>
<mvts>
<mvts_S att="a1">
<x>x1</x>
<w>w1</w>
</mvts_S>
<mvts_S>
<x>x2</x>
<w>w2</w>
</mvts_S>
</mvts>
</dl190Response>
所有这些都在 wsdl 中整齐地定义:
<?xml version="1.0" encoding="UTF-8"?>
<definitions
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://pse/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
name="PSE"
targetNamespace="http://pse/">
<types>
<xs:schema xmlns="http://pse/" targetNamespace="http://pse/">
<xs:complexType name="cdhead_T">
<xs:attribute name="cisprik" type="xs:long"/>
</xs:complexType>
<xs:complexType name="mvts_T">
<xs:sequence>
<xs:element name="mvts_S" type="mvts_S_T" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="mvts_S_T">
<xs:sequence>
<xs:element name="x" type="xs:string"/>
<xs:element name="w" type="xs:string"/>
</xs:sequence>
<xs:attribute name="att" type="xs:string" use="optional"/>
</xs:complexType>
</xs:schema>
</types>
<message name="DL190Req">
<part name="cdhead" type="tns:cdhead_T"/>
</message>
<message name="DL190Res">
<part name="cdhead" type="tns:cdhead_T"/>
<part name="mvts" type="tns:mvts_T"/>
</message>
<portType name="DLPortType">
<operation name="dl190">
<input message="tns:DL190Req"/>
<output message="tns:DL190Res"/>
</operation>
</portType>
<binding name="DLBinding" type="tns:DLPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="dl190">
<soap:operation soapAction="http://www.testServer.com/test_soap.php#dl190"/>
<input>
<soap:body use="literal" namespace="http://pse/"/>
</input>
<output>
<soap:body use="literal" namespace="http://pse/"/>
</output>
</operation>
</binding>
<service name="PSE">
<port name="DLPortType" binding="tns:DLBinding">
<soap:address location="http://www.testServer.com/test_soap.php"/>
</port>
</service>
</definitions>
我一直在服务器端 test_soap.php 无休止地工作以使其正确,但我没有成功。在返回 XML 之前正常工作的部分内容如下:
<?php
class PSE {
function dl190 ($arg) {
//I don't need to extract the input data just now
mysql_connect('127.0.0.1:3306', 'user', 'password');
mysql_select_db('myDatabase');
$xml = new SimpleXMLElement('<dl190Res/>');
$xml -> addChild('cdhead');
$mvts = $xml -> addChild('mvts');
$rows = mysql_query('select * from trx');
while($data = mysql_fetch_assoc($rows)) {
$mvts_S = $mvts -> addChild('mvts_S');
foreach($data as $key => $value) {
if ($key == 'att') { $mvts_S -> addAttribute($key, $value);}
else {$mvts_S -> addChild($key, $value);}
}
};
$dom = dom_import_simplexml ($xml) -> ownerDocument;
// now respond to the request and return the XML
}
};
ini_set( "soap.wsdl_cache_enabled", "0");
$server = new SoapServer ("test.wsdl");
$server -> setClass ('PSE');
$server -> setObject (new PSE());
$server -> handle();
?>
我几乎尝试了我能想到的所有方法来得到正确的响应,但我没有成功。我能够对之前仅包含一个部分的消息执行相同的操作(请参阅我最近的问题+答案)。
但是在这里,有两个消息部分,我没有成功。
$xml 内容的调试表明它正是我希望看到的返回,当然,在让肥皂服务器将其包装到 Envelope+Body 之后。
实际上,这种情况与只有一个消息部分的情况不同:只要我先剥离 XML 声明,然后返回它,我就可以从一个部分创建一个新的 SoapVar。在这里我不能这样做,因为返回值由两部分组成。
所以我想知道我现在应该做什么:
- 为响应消息声明一个类并填充并返回它
- 使用 SoapVar 和/或 SoapParam 执行一些魔术(请注意,我已经尝试了很多)
- 使用数组和 SoapVar 执行一些魔术(已经尝试了很多)
- 不知何故(如何?)向wsdl寻求帮助
- 完全不同的东西
- 用 SoapServer 退出整个噩梦,从头开始创建我自己的 http 响应
我感谢所有的帮助,所以所有的肥皂专家,不要犹豫,试着回答这个问题!
添加
作为临时解决方法,我编辑了 WSDL,将响应消息更改为只有一个部分。这允许我将预期的消息作为预期的两个部分的串联传递(或任何其他消息,因为 SoapVar 没有对返回的值进行消息定义的结构 WSDL 检查):
$xml1 = new SimpleXMLElement('<cdhead/>');
$xml1 -> addAttribute ('xmlns', 'http://pse/');
$xml1 -> addAttribute ('cisprik', $newCisprik);
$xml2 = new SimpleXMLElement('<mvts/>');
$rows = mysql_query('select * from trx');
while($data = mysql_fetch_assoc($rows)) {
$mvts_S = $xml2 -> addChild('mvts_S');
foreach($data as $key => $value) {
if ($key == 'att') { $mvts_S -> addAttribute($key, $value);}
else {$mvts_S -> addChild($key, $value);}
}
};
$dom1 = dom_import_simplexml ($xml1) -> ownerDocument;
$dom2 = dom_import_simplexml ($xml2) -> ownerDocument;
$part1 = $dom1 -> saveXML($dom1 -> documentElement);
$part2 = $dom2 -> saveXML($dom2 -> documentElement);
$result = new SoapVar ($part1 . $part2, XSD_ANYXML);
对此的特殊之处在于,连接当然不是有效的 XML,缺少周围的根元素,但 SoapVar 无论如何都能解析它。
就是这样:任何对 SoapVar 和 SoapParam / SoapServer 有详细了解的人都可以解释是否有可能返回两个消息部分?
并解释如何做到这一点?
或者,提供有关如何在其他 SOAP 设置中执行此操作的详细信息?