Как анализировать XML с несколькими изменяющимися пространствами имен? - PullRequest
2 голосов
/ 15 января 2011

У меня есть следующий 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 Ответ

1 голос
/ 15 января 2011

Изменение URI пространства имен для отражения изменения версии в схеме - это то, что люди чувствуют себя действительно умно, но в большинстве случаев это действительно плохая идея, и они должны знать лучше.Он просто создан для того, чтобы вам, потребителю XML, стало все труднее.

Теоретически вы должны взглянуть на документацию, чтобы увидеть, есть ли какое-либо значимое различие между двумя пространствами имен, которые необходимо учитывать,Вероятно, нет.

Ваш подход выглядит довольно хрупким, поскольку он основан на том, что префиксы пространства имен более стабильны, чем URI.Прагматично, возможно, они есть, но не стоит полагаться на это.

Моя обычная рекомендация при работе с вариантами пространства имен - сначала преобразовать файл, чтобы использовать стандартное пространство имен.В этом случае у меня возникнет искушение сделать это путем простой подстановки текста перед выполнением анализа XML.

...