在PHP中解析XML:无法将String解析为XML

时间:2017-03-30 12:58:56

标签: php xml parsing soap simplexml

我想将从SOAP服务返回的XML解析为PHP arra。以下是样本回复:

https://gist.github.com/anonymous/0c83d7d8789f844575e3fd78434a970d

以下代码中上面的网址内容为response

    ...
    $client = new \SoapClient($wsUrl);
    $result = $client->__soapCall(
        "GetList",
        [],
        Null,
        $header
    );
    if (is_soap_fault($result)) {
        trigger_error("SOAP Fault: (faultcode: {$result->faultcode}, faultstring: {$result->faultstring})", E_USER_ERROR);
    } else {
        return $result;
    }
    $sxe = new \SimpleXMLElement($result);
    $sxe->registerXPathNamespace('d', 'urn:schemas-microsoft-com:xml-msdata');
    $result = $sxe->xpath("//NewDataSet");
    ...

获取以下错误:

String could not be parsed as XML. SimpleXMLElement::__construct(): Entity: line 1: parser error : Extra content at the end of the document

我做错了什么?

1 个答案:

答案 0 :(得分:1)

以下是问题中链接的代码的重新格式化示例(注意:如果外部链接无法访问,最好直接包含此类示例)。

<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:MainDataTable="rows" msdata:UseCurrentLocale="true">
        <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded">
                <xs:element name="rows">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="id" type="xs:int" minOccurs="0"/>
                            <xs:element name="semt" type="xs:string" 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">
    <DocumentElement xmlns="">
        <rows diffgr:id="rows1" msdata:rowOrder="0">
            <id>1</id>
            <semt>_</semt>
        </rows>
        <!-- many more "rows" blocks similar to the above -->
    </DocumentElement>
</diffgr:diffgram>

像这样格式化,很明显有两个不同的根元素<xs:schema>...</xs:schema><diffgr:diffgram>...</diffgr:diffgram>。有效的XML文档必须具有单个根节点,因此这是解析器检测到的错误。 (&#34;文档的结尾&#34;就其而言是&#34; </xs:schema>&#34;,所以&#34;额外的内容&#34;是整个块开始于&#34; <diffgr:diffgram&#34;。)

看看这两个块,很清楚它们实际上是作为两个不同的XML文档:一个是架构(预期格式的描述),另一个是记录本身。

您可以通过以下两种方式之一处理此问题:

  • 将字符串分成两部分,例如通过查找"<diffgr"的第一次出现(如果XML的格式稍有变化,这可能会中断)。
  • 将字符串包裹在假的额外元素中,例如$xml = "<dummy>$response</dummy>,以便结果是有效的XML文档