views:

439

answers:

3

I've loaded a XML document, and now I wish to run a XPath query to select a certain subset of the XML. The XML is

<?xml version="1.0"?>
<catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'&gt;
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with
      XML.</description>
   </book>
</catalog>

and the procedure goes something like

procedure RunXPathQuery(XML: IXMLDOMDocument2; Query: string);
begin

  XML.setProperty('SelectionLanguage', 'XPath');

  NodeListResult := XML.documentElement.selectNodes(Query));

  ShowMessage('Found (' + IntToStr(NodeListResult.length) + ') nodes.');

end;

Problem is: when I run the XPath query '/catalog' for the above XML, it returns (as expected) a nodelist of 1 element. However, if I remove :xsi from <catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'&gt; and re-run the query, the nodelist returned is empty. If I remove the entire 'xmlns'-attribute, the resulting nodelist has, once again, 1 element.

So my question is this: what can I do to remedy this, i.e. how do I make MSXML return the correct number of instances (when running a XPath query), regardless of the namespace (or other attributes)?

Thanks!

+2  A: 

See this link!

When you use <catalog xmlns='http://www.w3.org/2001/XMLSchema-instance'&gt; then the whole node will be moved to a different (default) namespace. Your XPath isn't looking inside this other namespace so it can't find any data. With <catalog xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'&gt; you're just declaring xsi as a different namespace. This would be a different namespace than the default namespace.

I can't test it right now but adding something like this might help:

XML.setProperty('SelectionNamespaces', 'xmlns=''http://www.w3.org/2001/XMLSchema-instance''');

Or maybe it doesn't. As I said, I can't test it right now.

Workshop Alex
Thanks Workshop Alex! That makes a lot of sense. Unfortunately, it doesn't seem to do the trick (yet), but I'll play around with it a little more.
conciliator
+1  A: 

Use:

document.setProperty('SelectionNamespaces', 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"')
sgrassie
... and then query for `/xsi:catalog` instead of just `/catalog`.
Rob Kennedy
+2  A: 

Figured it out. It seems that my problem has been described here and here (and most likely a zillion other places, too).

The query /*[local-name()='catalog'] works for me.

conciliator