Reference to undeclared namespace prefix when parsing MSXML
Asked Answered
M

3

19

How do I solve the

Reference to undeclared namespace prefix: '%s'

problem with Microsoft's msxml implementation?


I'm using an XML feed from a government web-site that contains values i need to parse. The xml contains namespaces:

<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns="http://purl.org/rss/1.0/"
    xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:dcterms="http://purl.org/dc/terms/"
    xmlns:xsi="http://www.w3c.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.w3c.org/1999/02/22-rdf-syntax-ns#rdf.xsd">
    <item rdf:about="http://www.bankofcanada.ca/stats/rates_rss/STATIC_IEXE0101.xml">
        <cb:statistics>
            <cb:exchangeRate>
                <cb:value decimals="4">1.0351</cb:value>
                <cb:baseCurrency>CAD</cb:baseCurrency>
                <cb:targetCurrency>USD</cb:targetCurrency>
                <cb:rateType>Bank of Canada noon rate</cb:rateType>
                <cb:observationPeriod frequency="daily">2011-05-09T12:15:00-04:00</cb:observationPeriod>
            </cb:exchangeRate>
        </cb:statistics>
    </item>
</rdf:RDF>

Running the XPath query:

/rdf:RDF/item/cb:statistics/cb:exchangeRate/cb:targetCurrency

fails with the error:

Reference to undeclared namespace prefix: 'rdf'

Edit:

If i edit the original XML to remove all use of namespaces:

<?xml version="1.0" encoding="ISO-8859-1"?>
<rdf>
    <item>
        <statistics>
            <exchangeRate>
                <value decimals="4">1.0351</value>
                <baseCurrency>CAD</baseCurrency>
                <targetCurrency>USD</targetCurrency>
                <rateType>Bank of Canada noon rate</rateType>
                <observationPeriod frequency="daily">2011-05-09T12:15:00-04:00</observationPeriod>
            </exchangeRate>
        </statistics>
    </item>
</rdf>

The query /rdf/item/statistics/exchangeRate/baseCurrency doesn't fail, and returns nodes:

<baseCurrency>CAD</baseCurrency>

How do i get Microsoft XML to work with namespaces?


Edit 2

i've tried adding SelectionNamespaces to the DOMDocument object:

doc.setProperty('SelectionNamespaces', 'xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"');

Now the xpath query doesn't fail, but it also returns no nodes:

nodes = doc.selectNodes('/rdf:RDF/item/cb:statistics/cb:exchangeRate/cb:targetCurrency');

See also

Mallard answered 10/5, 2011 at 14:29 Comment(0)
C
23

Using SelectionNamespaces is the correct approach, you are just missing a namespace.

Notice that your XML document explicitly sets the default namespace as follows:

xmlns="http://purl.org/rss/1.0/"

This means that any element without a prefix, such as the item element, is actually in the default namespace. So if you want to select that element with an XPath expression, you must first set an appropriate selection namespace.

To do this, you can change your call to setProperty like so:

doc.setProperty('SelectionNamespaces', 'xmlns:rss="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"');

Here you've assigned the default namespace from the document to the rss: prefix in your XPath expression. With that change in place, the following XPath expression should work correctly:

nodes = doc.selectNodes('/rdf:RDF/rss:item/cb:statistics/cb:exchangeRate/cb:targetCurrency');

It works because it references the item element using the correct namespace. The fact that the prefix differs between the XPath expression and the original document is immaterial. It is the namespace which the prefix is bound to that matters.

Comptometer answered 11/5, 2011 at 8:50 Comment(3)
Wow, that works. That actually works. i don't know how it works. But it works.Mallard
It works because your "item" element is in the default namespace ("purl.org/rss/1.0/") and you have to explicitly set it in the XPath search. You set "rss" to the default namespace and search for it explicitly by rss:item. You could change the name of the default namespace "rss" to something you want.Shope
True Life saver indeed. Have been looking for this a long time. Works in Excel VBA!Faustofaustus
V
1
doc.setProperty('SelectionNamespaces', 'xmlns:rss="http://purl.org/rss/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:cb="http://www.cbwiki.net/wiki/index.php/Specification_1.1"');

Dont forget to load the xsd file or schema to the xmldoc object

is the way to go

I dont have enough reputation to comment. But that bit there saved me a lot of time.

Thank you so much

Vanettavang answered 19/11, 2014 at 22:34 Comment(0)
N
1

If you are using XMLSerializer and see this error, it is likely that you are running into the IE bug described here:

https://stackoverflow.com/a/11399681

It took me a lot of time to realize that this was happening, so I thought it best to link these two issues.

Nailhead answered 8/6, 2015 at 15:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.