【问题标题】:How to parse complicated XML如何解析复杂的 XML
【发布时间】:2016-01-13 05:12:33
【问题描述】:

我有这种结构的 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>

【问题讨论】:

  • 看起来它被解析了。你在问什么?
  • @pvg,我希望得到这个消息 292901PendingPending
  • 这不仅仅是 XML,它是 SOAP。 PHP 对此有一个特定的扩展。

标签: php xml parsing


【解决方案1】:

可能的解决方案是使用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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多