【问题标题】:Soap response can't be parsed with SimpleXML无法使用 SimpleXML 解析 Soap 响应
【发布时间】:2012-03-05 16:53:28
【问题描述】:

我正在使用本机 soapclient() 来调用 WSDL,但我不能使用 simplexml 来解析结果。我一直收到一个错误:

Warning: simplexml_load_string() [function.simplexml-load-string]: 
Entity: line 1: parser error : Extra content at the end of the document

这看起来不像是命名空间问题,我已经尝试了网站上其他地方提到的补丁来删除输入字符串中的冒号。

编辑:

谢谢,戈登

是的,你是对的。服务器是使用数据集的 Microsoft 站点。

如果我声明带有跟踪设置为 true 的肥皂客户端:

$soapClient = new soapclient($this->wsdlUrl,array('trace'=>true));

然后从响应中检索原始 XML:

$soapResult = $soapClient->GetScheduledSectors();
$responseXml = $soapClient->__getLastResponse();
$xml = simplexml_load_string($responseXml, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");

然后我得到:

SimpleXMLElement Object
(
    [Body] => SimpleXMLElement Object
        (
        )
)

响应 XML 标头和第一个标记如下所示:

<?xml version='1.0'?> 
<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>

  <GetScheduledSectorsResponse xmlns="https://www.kulula.com/k3api/">

     <GetScheduledSectorsResult msdata:SchemaSerializationMode="ExcludeSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">

        <xs:schema id="dsFlight" targetNamespace="http://tempuri.org/dsFlight.xsd" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:mstns="http://tempuri.org/dsFlight.xsd" xmlns="http://tempuri.org/dsFlight.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">

           <xs:element name="dsFlight" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:ExecutionTime="1140">

              <xs:complexType>

                 <xs:choice minOccurs="0" maxOccurs="unbounded"/>

              </xs:complexType>

           </xs:element>

        </xs:schema>

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

           <dsFlight xmlns="http://tempuri.org/dsFlight.xsd">

              <FlightSector diffgr:id="FlightSector1" msdata:rowOrder="0">

                 <FlightSectorId>1</FlightSectorId>

                 <FlightSectorName>JNBCPT</FlightSectorName>

                 <FromAirport>O.R. Tambo (Jo'burg)</FromAirport>

                 <ToAirport>Cape Town</ToAirport>

                 <DepartureAirportId>1</DepartureAirportId>

                 <ArrivalAirportId>2</ArrivalAirportId>

                 <AirlineCode>BA</AirlineCode>

                 <Ordernumber>100</Ordernumber>

                 <FlightZoneId>1</FlightZoneId>

                 <DepartureCountryCode>ZA</DepartureCountryCode>

                 <DepartureContinentCode>AF</DepartureContinentCode>

              </FlightSector>

我也尝试过注册以下命名空间:

$xml = simplexml_load_string($this->responseXml, NULL, NULL, "http://schemas.xmlsoap.org/soap/envelope/");
    $xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
    $xml->registerXPathNamespace('xsi', 'http://www.w3.org/2001/XMLSchema-instance');
    $xml->registerXPathNamespace('xsd', 'http://www.w3.org/2001/XMLSchema');
    $xml->registerXPathNamespace('diffgr', 'urn:schemas-microsoft-com:xml-diffgram-v1');
    $xml->registerXPathNamespace('mstns', 'http://tempuri.org/dsFlight.xsd');
    $xml->registerXPathNamespace('msprop', 'urn:schemas-microsoft-com:xml-msprop');

但仍然在 $xml 中得到一个空对象

【问题讨论】:

  • 好像没有根元素

标签: php soap


【解决方案1】:

您可以尝试使用 DOMDocument 而不是 simpleXML,因为在我过去的使用中,它似乎更容错。不过几乎没有那么快。

然而,当我需要解析 SOAP 时,我参考了How to parse SOAP XML?,并找到了关于 PHP 5 原生 Soap 客户端的优秀信息。

【讨论】:

    【解决方案2】:

    我有同样的问题,然后我试试:

    $soapResult = $soapClient->GetScheduledSectors();
    $responseXml = $soapClient->__getLastResponse();
    
    $dom = new DomDocument();
    $dom->loadXML($responseXml );
    
    $phpObject = simplexml_load_string($dom->textContent);
    print_r($phpObject ); 
    

    然后看看结果。

    【讨论】:

      【解决方案3】:

      我也遇到过这个问题。 在联系 Web 服务开发人员后,我得到的答案是这个响应不是 XML,而是 DATATABLE(这是一个 c# 数据类型)。

      最后我的解决方案是创建自己的解析器,而不是使用原生 PHP 解析器。

      根据相关字段尝试使用explode()。 我知道这不是最佳解决方案(绝对不是最佳实践),但是如果您无法以其他格式获得它,这可能对您有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-26
        相关资源
        最近更新 更多