本文介绍在使用对象的 selectSingleNode 和 selectNodes
方法 IXMLDOMNode
进行 XPath 查询时,必须使用限定名称。
原始产品版本: Microsoft XML 分析器
原始 KB 数: 294797
总结
使用 XML 分析器 (MSXML) 3.0 版本, XPath
可以方便地查询 XML 文档并返回节点或节点集。 在使用XPath
查询以及selectSingleNode
和selectNodes
方法与IXMLDOMNode
对象配合时,必须使用限定名称。 例如,要选择带有以下 XML 数据的 Book 节点:
<?xml version ="1.0"?>
<a:Books xmlns:a="x-schema:bookschema.xml" >
<a:Book>
<title>Presenting XML</title>
<author>Richard Light</author>
</a:Book>
</a:Books>
如果我们用 a 作为 x-schema:bookschema.xml
统一资源标识符 (URI) 的别名,则相应的 XPath 查询如下:
pXMLDoc->setProperty("SelectionNamespaces","xmlns:a='x-schema:bookschema.xml'");
pXMLDoc->documentElement->selectNodes("/a:Books/a:Book");
在这种情况下,使用限定的名称非常简单。 但是,使用默认命名空间时,使用限定名称可能更加困难,如以下示例所示:
<?xml version ="1.0"?>
<Books xmlns="x-schema:bookschema.xml" >
<Book>
<title>Presenting XML</title>
<author>Richard Light</author>
</Book>
</Books>
注意
节点标记中不使用前缀。 限定名称仍必须在 XPath 查询中使用,否则查询(例如 ,/Books/Book)不会返回任何结果,因为没有匹配的节点。
详细信息
提供了以下 Visual C++ 示例来演示技术。
若要在使用 XPath 查询 DOM 时指定命名空间,请执行以下步骤:
创建 Win32 控制台项目,并向项目添加新.cpp文件。 将以下代码粘贴到.cpp文件中,并将文件命名为Test.cpp:
#include <stdio.h> #import "msxml3.dll" using namespace MSXML2; void dump_com_error(_com_error &e); int main(int argc, char* argv[]) { CoInitialize(NULL); try{ IXMLDOMDocument2Ptr pXMLDoc; HRESULT hr = pXMLDoc.CreateInstance(__uuidof(DOMDocument)); pXMLDoc->async = false; // default - true, pXMLDoc->validateOnParse = true; hr = pXMLDoc->load("books.xml"); if(hr!=VARIANT_TRUE) { IXMLDOMParseErrorPtr pError; pError = pXMLDoc->parseError; _bstr_t parseError =_bstr_t("At line ")+ _bstr_t(pError->Getline()) + _bstr_t("\n")+ _bstr_t(pError->Getreason()); MessageBox(NULL,parseError, "Parse Error",MB_OK); return -1; } hr = pXMLDoc->setProperty("SelectionLanguage", "XPath"); hr = pXMLDoc->setProperty("SelectionNamespaces", "xmlns:a='x-schema:bookschema.xml'"); IXMLDOMNodeListPtr pNodeList; pNodeList = pXMLDoc->documentElement->selectNodes("/a:Books/a:Book"); int count = pNodeList->Getlength(); char pLength[64]; sprintf(pLength, "Total number of nodes selected is %d", count); MessageBox(NULL,pLength,"Test", MB_OK); } catch(_com_error &e) { dump_com_error(e); return -1; } return 0; } void dump_com_error(_com_error &e) { printf("Error\n"); printf("\a\tCode = %08lx\n", e.Error()); printf("\a\tCode meaning = %s", e.ErrorMessage()); _bstr_t bstrSource(e.Source()); _bstr_t bstrDescription(e.Description()); printf("\a\tSource = %s\n", (LPCSTR) bstrSource); printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription); }
将以下 XML 另存为Books.xml与Test.cpp相同的项目文件夹中。
<?xml version ="1.0"?> <Books xmlns="x-schema:bookschema.xml" > <Book> <title>Presenting XML</title> <author>Richard Light</author> <pages>334</pages> </Book> <Book> <title>Mastering XML</title> <author>John Smith</author> <pages>209</pages> </Book> </Books>
将以下 XML 另存为与Test.cpp相同的项目文件夹中Bookschema.xml。
<?xml version="1.0"?> <Schema xmlns="urn:schemas-microsoft-com:xml-data"> <ElementType name="title" /> <ElementType name="author" /> <ElementType name="pages" /> <ElementType name="Book" model="closed"> <element type="title" /> <element type="author" /> <element type="pages" /> </ElementType> <ElementType name="Books" model="closed"> <element type="Book" /> </ElementType> </Schema>
编译并运行该应用程序。 消息框显示查询返回
XPath
的节点数。 参阅以下内容:同一示例代码可与显式 URI 一起使用作为命名空间。
在以下行中
IXMLDOMDocument2Ptr pXMLDoc; ... hr = pXMLDoc->setProperty("SelectionLanguage", "XPath"); hr = pXMLDoc->setProperty("SelectionNamespaces", "xmlns:a='x-schema:bookschema.xml'"); ... pNodeList = pXMLDoc->documentElement->selectNodes("/a:Books/a:Book");
setProperty
方法在IXMLDOMDocument
接口中不可用。
限定名称(QName)由前缀和本地部分组成。 该前缀提供限定名称的命名空间前缀,并且必须与命名空间 URI 相关联。