XPath を使用して DOM にクエリを実行するときに名前空間を指定する
この記事では、オブジェクトの selectSingleNode メソッドと selectNodes
メソッドで XPath クエリを使用する場合は、修飾名を使用する IXMLDOMNode
必要があることを説明します。
元の製品バージョン: Microsoft XML パーサー
元の KB 番号: 294797
概要
XML パーサー (MSXML) 3.0 リリースでは、XML ドキュメントのクエリを実行し、 XPath
ノードまたはノード セットを返す便利な方法が提供されます。 オブジェクトの メソッドと selectNodes
メソッドでselectSingleNode
クエリをIXMLDOMNode
使用XPath
する場合は、修飾名を使用する必要があります。 たとえば、次の 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>
を Uniform Resource Identifier (URI) のエイリアスとして使用する x-schema:bookschema.xml
場合、対応する 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 をTest.cppと同じプロジェクト フォルダーに Books.xml として保存します。
<?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 に関連付ける必要があります。