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 にクエリを実行するときに名前空間を指定するには、次の手順に従います。

  1. 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);
    }
    
  2. 次の 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>
    
  3. 次の 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>
    
  4. アプリケーションをコンパイルして実行します。 メッセージ ボックスには、クエリによって返されるノードの数が 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 に関連付ける必要があります。

関連情報

XPath を使用してユーザー定義の既定の名前空間に対してクエリを実行する方法