MSXML 6.0: Matching Nodes Are Not Returned When You Run XPath Queries Against XML Documents that Specify a Default Namespace Declaration
This article helps you resolve the problem where matching nodes are not returned when you run XPath queries against XML documents that specify a default namespace declaration.
Original product version: Microsoft XML
Original KB number: 313372
Symptoms
When you use the MSXML 6.0 Document Object Model (DOM) methods (selectNodes
and selectSingleNode
) to run XPath queries against an XML document that specifies a default namespace declaration, the matching node or nodes are not returned.
Cause
The default namespace declaration is not added to the Namespace names of the DOMDocument object, or a namespace prefix is not specified for the default namespace declaration when it is added to the Namespace names of the DOMDocument object.
Resolution
Add the default namespace declaration to the Namespace names of the DOMDocument object by specifying a namespace prefix. To do this, use the setProperty
method of the DOMDocument object to set the SelectionNamespaces
internal property.
More information
MSXML 6.0 no longer supports the XSLPattern query language. It only supports the XPath query language. This implies that simple tree-style hierarchical queries to access nodes in an XML document are also run as XPath queries in MSXML 6.0. When you use the MSXML 6.0 DOM to run XPath queries against an XML document that specifies a default namespace declaration, you must use the setProperty
method of the DOMDocument
object to add the default namespace declaration by specifying a namespace prefix, to the Namespace names of the DOMDocument
object.
Steps to reproduce behavior
To recreate the problem and test the specified resolution by using a Visual Basic Standard EXE project, follow these steps:
In Notepad, create an XML document that contains the following XML named Books.xml in the root folder of drive
C:
.<?xml version='1.0'?> <Books xmlns="urn:books"> <Book> <Title>Beginning XML</Title> <Publisher>Wrox</Publisher> </Book> <Book> <Title>XML Step by Step</Title> <Publisher>MSPress</Publisher> </Book> <Book> <Title>Professional XML</Title> <Publisher>Wrox</Publisher> </Book> <Book> <Title>Developing XML solutions</Title> <Publisher>MSPress</Publisher> </Book> </Books>
In Visual Basic, create a new Standard EXE project.
Add a reference to Microsoft XML, version 6.0.
Drag a command button onto Form1.
Paste the following code in the Click event procedure of the command button:
Note
This code loads the sample Books.xml document into an instance of the MSXML 6.0
DOMDocument60
object. It then uses the SelectNodes DOM method to run an XPath query against theDOMDocument60
object to identify the titles that are published by MSPress.Dim xmldoc As MSXML2.DOMDocument60 Dim bookList As MSXML2.IXMLDOMNodeList Dim bookNode As MSXML2.IXMLDOMNode Set xmldoc = New MSXML2.DOMDocument60 'xmldoc.setProperty "SelectionNamespaces", "xmlns:bk='urn:books'" xmldoc.Load "c:\books.xml" Set bookList = xmldoc.selectNodes("//Publisher[. = 'MSPress']/parent::node()/Title")'Set bookList = xmldoc.selectNodes("//bk:Publisher[. = 'MSPress']/parent::node()/bk:Title") For Each bookNode In bookList Debug.Print "Title : " & bookNode.Text Next
Save and run the project.
Click the command button when the form is displayed. Although the XPath query is valid, it does not generate any results, and the matching titles are not written to the Visual Basic Immediate window.
Stop the project.
Uncomment the following line of code immediately after the
Set xmldoc = New MSXML2.DOMDocument60
statement to add the default namespace declaration by specifying a namespace prefix to the Namespace names of theDOMDocument
object:'xmldoc.setProperty "SelectionNamespaces", "xmlns:bk='urn:books'"
Comment the call to the
selectNodes
DOM method that is used to execute the XPath query.Set bookList = xmldoc.selectNodes("//Publisher[. = 'MSPress']/parent::node()/Title")
Uncomment the following statement:
'Set bookList = xmldoc.selectNodes("//bk:Publisher[. = 'MSPress']/parent::node()/bk:Title")
Note
The element names are now prefixed with the bk namespace alias that you specify when the default namespace declaration is added to the Namespace names of the
DOMDocument
object.Save and run the project. Click the command button when the form is displayed. The matching nodes are listed in the Visual Basic Immediate window.