用php解析SOAP XML响应


parsing SOAP XML response with php

我已经查看了多个示例和w3Schools教程,但我不知道SOAP响应的结构。我已经10多年没有接触php/xml了,所以你可以认为我是初学者。

这是我收到的回复样本

<DataSet xmlns="http://www.multiprets.net/api">
    <xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="NewDataSet">
        <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
            <xs:complexType>
                <xs:choice minOccurs="0" maxOccurs="unbounded">
                    <xs:element name="Table">
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name="ProductSequence" type="xs:string" minOccurs="0"/>
                                <xs:element name="ProductCode" type="xs:string" minOccurs="0"/>
                                <xs:element name="ProdNameEn" type="xs:string" minOccurs="0"/>
                                <xs:element name="ProdNameFr" type="xs:string" minOccurs="0"/>
                                <xs:element name="ProductTerm" type="xs:double" minOccurs="0"/>
                                <xs:element name="UpdDate" type="xs:int" minOccurs="0"/>
                                <xs:element name="UpdTime" type="xs:int" minOccurs="0"/>
                                <xs:element name="Posted" type="xs:double" minOccurs="0"/>
                                <xs:element name="MPH" type="xs:double" minOccurs="0"/>
                                <xs:element name="CNT" type="xs:int" minOccurs="0"/>
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                </xs:choice>
            </xs:complexType>
        </xs:element>
    </xs:schema>
    <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
        <NewDataSet xmlns="">
            <Table diffgr:id="Table1" msdata:rowOrder="0">
                <ProductSequence>A1999</ProductSequence>
                <ProductCode>VC</ProductCode>
                <ProdNameEn>3 years variable</ProdNameEn>
                <ProdNameFr>3 ans variable</ProdNameFr>
                <ProductTerm>3</ProductTerm>
                <UpdDate>20140529</UpdDate>
                <UpdTime>134900</UpdTime>
                <Posted>3</Posted>
                <MPH>3</MPH>
                <CNT>1</CNT>
            </Table>
            <Table diffgr:id="Table2" msdata:rowOrder="1">
                <ProductSequence>A4000</ProductSequence>
                <ProductCode>VC</ProductCode>
                <ProdNameEn>5 years variable</ProdNameEn>
                <ProdNameFr>5 ans variable</ProdNameFr>
                <ProductTerm>5</ProductTerm>
                <UpdDate>20141021</UpdDate>
                <UpdTime>103100</UpdTime>
                <Posted>3</Posted>
                <MPH>2.3</MPH>
                <CNT>1</CNT>
            </Table>

我尝试使用以下代码从table8获取<MPH>标签:

$client = new soapclient("http://www.multiprets.net/api/ws/services.asmx?wsdl"); 
$objectresult = $client->Recupere_meilleurs_Taux(array('Code_businessID'=> '**LoginString**','trace' => 1)); 
$resultat = simplexml_load_string($objectresult->Recupere_meilleurs_TauxResult->any); 
foreach ($resultat->xpath('//Table[@id='Table8']') as $product){ echo $product->MPH."< br/ >"; }

没有用,因为它没有返回任何结果。如果我从xpath中删除该属性并只保留//Table,我将从所有表中获得MPH,因此我确信它具有属性@id

提前感谢您抽出时间和分享您的知识。

这里的问题是您的属性有一个名称空间,所以您需要用SimpleXMLXPath注册ns,并在XPath查询中使用它。

此元素为其子元素声明了两个名称空间:

<diffgr:diffgram 
    xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
    xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">

要使用SimpleXML注册这些名称空间,需要使用函数registerXPathNamespace。根据您正在执行的其他查询,您可能需要注册这两个名称空间。对于您的查询,您需要urn:schemas-microsoft-com:xml-diffgram-v1diffgr)命名空间;像这样注册:

$sxe = new SimpleXMLElement($your_xml_here);
$sxe->registerXPathNamespace('d', 'urn:schemas-microsoft-com:xml-diffgram-v1');

现在,您可以访问diffgr名称空间中的任何元素或属性,方法是在其前面加上字母d。以下是使用id为Table1:的Table元素的示例

$tables = $sxe->xpath('//Table[@d:id="Table1"]');
foreach ($tables as $t) {
    echo $t->ProductSequence . PHP_EOL;
}

输出:

A1999
retrieve value from this type response 

<?xml version="1.0" encoding="utf-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
        <soap:Body>
            <xyzResponse xmlns="http://tempuri.org/">
                <xyzResult>
                    <xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
                        <xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
                            <xs:complexType>
                                <xs:choice minOccurs="0" maxOccurs="unbounded">
                                    <xs:element name="Table">
                                        <xs:complexType>
                                            <xs:sequence>
                                                <xs:element name="myCityID" type="xs:int" minOccurs="0" />
                                                <xs:element name="myCityName" type="xs:string" minOccurs="0" />
                                                <xs:element name="myLat" type="xs:double" minOccurs="0" />
                                                <xs:element name="myLon" type="xs:double" minOccurs="0" />
                                            </xs:sequence>
                                        </xs:complexType>
                                    </xs:element>
                                </xs:choice>
                            </xs:complexType>
                        </xs:element>
                    </xs:schema>
                    <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
                        <NewDataSet xmlns="">
                            <Table diffgr:id="Table1" msdata:rowOrder="0">
                                <CityID>1</CityID>
                                <CityName>Ahmedabad</CityName>
                                <Lat>23.045839</Lat>
                                <Lon>72.550578</Lon>
                            </Table>
                            <Table diffgr:id="Table2" msdata:rowOrder="1">
                                <CityID>21</CityID>
                                <CityName>Amritsar</CityName>
                                <Lat>31.705603</Lat>
                                <Lon>74.807337</Lon>
                            </Table>
                        </NewDataSet>
                    </diffgr:diffgram>
                </xyzResult>
            </xyzResponse>
        </soap:Body>
    </soap:Envelope>

使用此代码,您可以轻松地获取$title变量中的所有Tables数据,并使用它可以轻松地获得任何特定值

                $sxe = new SimpleXMLElement($response);
                $sxe->registerXPathNamespace('d', 'urn:schemas-microsoft-com:xml-diffgram-v1');
                $result = $sxe->xpath("//NewDataSet");
                echo "<pre>";
                //print_r($result[0]);
                foreach ($result[0] as $title) {
                    print_r($title);
                }