0

我试图弄清楚如何使用 Laminas SOAP Autodiscover 生成多级 XML,但我无法做到。

我阅读了文档,但找不到解决方法。这是链接https://docs.laminas.dev/laminas-soap/auto-discovery/

这是我需要的输出:

<Header>
 <item1>?</item1>
 <item2>?</item2>
<Line>
 <item3>?</item3>
 <item4>?</item4>
</Line>
</Header>

但是我找不到一种方法来告诉 AutoDiscover 一个头部(Header 标记,它将包含一些标记和一个名为 Line 的子标记)。生成的唯一 WSDL 是从函数中删除 Header 和 Line。

Class Soap
{
 public function test($item1,$item2,$item3,$item4) {
 return;
}
}

$serverUrl = "http://localhost/api.php";
$options = [
    'uri' => $serverUrl,
];
$server = new \Laminas\Soap\Server(null, $options);

if (isset($_GET['wsdl'])) {
    $soapAutoDiscover = new \Laminas\Soap\AutoDiscover(new \Laminas\Soap\Wsdl\ComplexTypeStrategy\ArrayOfTypeSequence());
    $soapAutoDiscover->setBindingStyle(array('style' => 'document'));
    $soapAutoDiscover->setOperationBodyStyle(array('use' => 'literal'));
    $soapAutoDiscover->setClass('Soap');
    $soapAutoDiscover->setUri($serverUrl);
    
    header("Content-Type: text/xml");
    echo $soapAutoDiscover->generate()->toXml();
} else {
    $soap = new \Laminas\Soap\Server($serverUrl . '?wsdl');
    $soap->setObject(new \Laminas\Soap\Server\DocumentLiteralWrapper(new Soap()));
    $soap->handle();
}

这将只输出一个包含四个项目的 WSDL:

<xsd:element name="test">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="item1" type="xsd:anyType"/>
<xsd:element name="item2" type="xsd:anyType"/>
<xsd:element name="item3" type="xsd:anyType"/>
<xsd:element name="item4" type="xsd:anyType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

任何帮助将不胜感激。

4

1 回答 1

2

前提:我不是 SOAP 或 Laminas 专家,但我目前正在研究这些项目。我知道这是一个老问题,但我在寻找不同的东西时遇到了这个问题。

像这样的方法应该输出像你提到的那样的结果:

     /**
     * Test
     * @param string $item1
     * @param string $item2
     * @param string $item3
     * @param string $item4
     * @return mixed
     */
    function test($item1,$item2,$item3,$item4) {
        // create output
        $output = new stdClass();
        
        // define Header
        $header = new stdClass();
        $header->item1 = $item1;
        $header->item2 = $item2;
        
        // define Line
        $line = new stdClass();
        $line->item3 = $item3;
        $line->item4 = $item4;
        
        // assembling output
        $output->Header = $header;
        $output->Header->Line = $line;
       
        return $output;
    }

WSDL 将类似于:

[...]
<message name="testIn">
<part name="item1" type="xsd:string"/>
<part name="item2" type="xsd:string"/>
<part name="item3" type="xsd:string"/>
<part name="item4" type="xsd:string"/>
</message>
<message name="testOut">
<part name="return" type="xsd:anyType"/>
</message>
[...]

要求:

<x:Envelope
    xmlns:x="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ser="http://localhost/soap/server.php?wsdl">
    <x:Header/>
    <x:Body>
        <ser:test>
            <ser:item1>a</ser:item1>
            <ser:item2>b</ser:item2>
            <ser:item3>c</ser:item3>
            <ser:item4>d</ser:item4>
        </ser:test>
    </x:Body>
</x:Envelope>

回复:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:ns1="http://localhost/soap/server.php?wsdl"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <ns1:testResponse>
            <return xsi:type="SOAP-ENC:Struct">
                <Header xsi:type="SOAP-ENC:Struct">
                    <item1 xsi:type="xsd:string">a</item1>
                    <item2 xsi:type="xsd:string">b</item2>
                    <Line xsi:type="SOAP-ENC:Struct">
                        <item3 xsi:type="xsd:string">c</item3>
                        <item4 xsi:type="xsd:string">d</item4>
                    </Line>
                </Header>
            </return>
        </ns1:testResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>
于 2021-11-12T17:12:56.603 回答