2

I have the following xml that I'm trying to parse and get the Account Data from

    <?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>

The following code sometimes work such that the I can see that children tags and values of CdmCollections. However, it doesnt always work for the same query.

Looking at the raw xml I can see the namespaces change, e.g. sometimes ns2="http://www.intuit.com/sb/cdm/qbo" (works) and other times ns2 = "http://www.intuit.com/sb/cdm/v2" (doesnt work). I thought by using the namespaces array I could handle that issue but its not working. Any suggestions how I can fix this?

$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 Answer 1

1

Changing a namespace URI to reflect a version change in the schema is something people feel really clever about, but it's a really bad idea in most cases, and they should know better. It's just designed to make things more difficult for you, the consumer of the XML.

In theory you should look at the documentation to see whether there is any meaningful difference between the two namespaces that you need to take account of. Probably there isn't.

Your approach looks pretty fragile because it's relying on the namespace prefixes being more stable than the URIs. Pragmatically, perhaps they are, but it's not a good idea to rely on it.

My usual recommendation when dealing with namespace variants is to convert the file first to use a standard namespace. In this case I'd be quite tempted to do it by a simple text substitution before doing the XML parsing.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks Michael. The strange thing is that the namespace might swap a couple of times over a 10 minute period. Very annoying!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.