如何解析复杂的XML

时间:2016-01-13 05:12:33

标签: php xml parsing

我有这种结构XML。我正在尝试将其解析为数组,但我遇到了问题。

<?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">
    <CheckDealNoStatusResponse xmlns="http://tempuri.org/">
        <CheckDealNoStatusResult>
            <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:MainDataTable="tbl" msdata:UseCurrentLocale="true">
                    <xs:complexType>
                        <xs:choice minOccurs="0" maxOccurs="unbounded">
                            <xs:element name="tbl">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="Temp1" type="xs:long" minOccurs="0" />
                                        <xs:element name="Temp2" type="xs:string" minOccurs="0" />
                                        <xs:element name="Temp3" 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">
                <NewDataSet xmlns="">
                    <tbl diffgr:id="tbl1" msdata:rowOrder="0">
                        <Temp1>12929011</Temp1>
                        <Temp2>Pending</Temp2>
                        <Temp3>Pending</Temp3>
                    </tbl>
                </NewDataSet>
            </diffgr:diffgram>
        </CheckDealNoStatusResult>
        <ErrorMsg />
    </CheckDealNoStatusResponse>
</soap:Envelope>

我试图以这种方式解析它

$parser = simplexml_load_string($smlString, "SimpleXMLElement", LIBXML_NOCDATA);

  echo "<br /><br /><br /><pre>";
        print_r( $parser );
        echo "</pre>";

但我只是得到了这个。

SimpleXMLElement Object
(
    [CheckDealNoStatusResponse] => SimpleXMLElement Object
        (
            [CheckDealNoStatusResult] => SimpleXMLElement Object
                (
                )

            [ErrorMsg] => SimpleXMLElement Object
                (
                )

        )

)

如何获取这些信息

 <Temp1>12929011</Temp1>
 <Temp2>Pending</Temp2>
 <Temp3>Pending</Temp3>

1 个答案:

答案 0 :(得分:0)

可能的解决方案可能是使用simplexml_load_string并使用registerXPathNamespace注册名称空间。 然后,您可以使用xpath方法查找元素。

例如:

$smlString = <<<SOURCE
<?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">
    <CheckDealNoStatusResponse xmlns="http://tempuri.org/">
        <CheckDealNoStatusResult>
            <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:MainDataTable="tbl" msdata:UseCurrentLocale="true">
                    <xs:complexType>
                        <xs:choice minOccurs="0" maxOccurs="unbounded">
                            <xs:element name="tbl">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="Temp1" type="xs:long" minOccurs="0" />
                                        <xs:element name="Temp2" type="xs:string" minOccurs="0" />
                                        <xs:element name="Temp3" 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">
                <NewDataSet xmlns="">
                    <tbl diffgr:id="tbl1" msdata:rowOrder="0">
                        <Temp1>12929011</Temp1>
                        <Temp2>Pending</Temp2>
                        <Temp3>Pending</Temp3>
                    </tbl>
                </NewDataSet>
            </diffgr:diffgram>
        </CheckDealNoStatusResult>
        <ErrorMsg />
    </CheckDealNoStatusResponse>
</soap:Envelope>
SOURCE;

$parser = simplexml_load_string($smlString, "SimpleXMLElement", LIBXML_NOCDATA);
$ns = $parser->getNamespaces(true);
$parser->registerXPathNamespace('tempuri', $ns['']);
$parser->registerXPathNamespace('diffgr', $ns['diffgr']);

$elements = $parser->xpath('//tempuri:CheckDealNoStatusResponse/tempuri:CheckDealNoStatusResult/diffgr:diffgram/NewDataSet/tbl');
$element = $elements[0];

var_dump($element->Temp1->__toString());
var_dump($element->Temp2->__toString());
var_dump($element->Temp3->__toString());

将导致:

string(8) "12929011"
string(7) "Pending"
string(7) "Pending"

$element变量的类型为SimpleXMLElement。例如,您可以访问同样属于SimpleXMLElement的'Temp1','Temp2'或'Temp3'属性,并使用他们的__toString()方法获取文本内容。

Demo