如何使用多个更改的命名空间解析xml?

时间:2011-01-15 01:46:29

标签: php xml soap xml-namespaces

我有以下xml,我正在尝试解析并从

获取帐户数据
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:SearchResults xmlns="http://www.intuit.com/sb/cdm/v2" xmlns:ns2="http://www.intuit.com/sb/cdm/qbo" xmlns:ns3="http://www.intuit.com/sb/cdm/qbopayroll/v1">
    <ns2:CdmCollections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Accounts">
        <Account>
            <Id idDomain="QBO">31</Id>
            <SyncToken>0</SyncToken>
            <MetaData>
                <CreateTime>2010-02-16T18:03:50-08:00</CreateTime>
                <LastUpdatedTime>2010-02-16T18:03:50-08:00</LastUpdatedTime>
            </MetaData>
            <Name>Accounts Payable</Name>
            <Subtype>AccountsPayable</Subtype>
            <CurrentBalance>34002.00</CurrentBalance>
        </Account>
        <Account>
            <Id idDomain="QBO">36</Id>
            <SyncToken>0</SyncToken>
            <MetaData>
                <CreateTime>2011-01-11T13:24:14-08:00</CreateTime>
                <LastUpdatedTime>2011-01-11T13:24:14-08:00</LastUpdatedTime>
            </MetaData><Name>Accounts Receivable (A/R)</Name>
            <Subtype>AccountsReceivable</Subtype>
            <CurrentBalance>1125.85</CurrentBalance>
        </Account>
    </ns2:CdmCollections>
    <ns2:Count>10</ns2:Count>
    <ns2:CurrentPage>1</ns2:CurrentPage>
</ns2:SearchResults>

以下代码有时会起作用,以便我可以看到子标签和CdmCollections的值。但是,它并不总是适用于同一个查询。

查看原始xml我可以看到名称空间发生了变化,例如:有时ns2 =“http://www.intuit.com/sb/cdm/qbo”(有效)和其他时间ns2 =“http://www.intuit.com/sb/cdm/v2”(不起作用)。我认为通过使用命名空间数组我可以处理该问题,但它无法正常工作。有什么建议我可以解决这个问题吗?

$account_xml = new SimpleXMLElement($account_query_response);


$namespaces = $account_xml->getNamespaces(true);
$account_xml->registerXPathNamespace('c', $namespaces["ns2"]);

$x = 0;
foreach($account_xml->xpath('//c:SearchResults') as $search) {
    echo "<br>row " . $x;
    $search->registerXPathNamespace('c', $namespaces["ns2"]);

    var_dump($search->xpath('//c:CdmCollections'));
}

1 个答案:

答案 0 :(得分:1)

更改名称空间URI以反映模式中的版本更改是人们非常聪明的事情,但在大多数情况下这是一个非常糟糕的主意,他们应该更清楚。它只是为了让您(XML的消费者)更加困难而设计。

理论上,您应该查看文档,看看您需要考虑的两个名称空间之间是否存在任何有意义的差异。可能没有。

您的方法看起来非常脆弱,因为它依赖于名称空间前缀比URI更稳定。实际上,或许它们是,但依靠它并不是一个好主意。

在处理命名空间变体时,我通常建议首先转换文件以使用标准命名空间。在这种情况下,在进行XML解析之前,我很想通过简单的文本替换来完成它。