Partager via


Spécifier l’espace de noms lorsque vous interrogez le DOM avec XPath

Cet article décrit que vous devez utiliser des noms qualifiés lorsque vous utilisez une requête XPath avec les méthodes selectSingleNode et selectNodes de l'objet IXMLDOMNode.

Version du produit d’origine : Analyseur Microsoft XML
Numéro de base de connaissances d’origine : 294797

Résumé

Avec la version 3.0 de l’analyseur XML (MSXML), XPath vous pouvez interroger facilement des documents XML et retourner un nœud ou un ensemble de nœuds. Lorsque vous utilisez la requête XPath avec les méthodes selectSingleNode et selectNodes de l’objet IXMLDOMNode, vous devez utiliser des noms qualifiés. Par exemple, pour sélectionner le nœud Book avec les données XML suivantes :

<?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>

si nous utilisons "a" comme alias de l’URI x-schema:bookschema.xml (Uniform Resource Identifier), la requête XPath correspondante est la suivante :

pXMLDoc->setProperty("SelectionNamespaces","xmlns:a='x-schema:bookschema.xml'");
pXMLDoc->documentElement->selectNodes("/a:Books/a:Book");

Dans ce cas, l’utilisation du nom qualifié est simple. Toutefois, lorsque l’espace de noms par défaut est utilisé, l’utilisation du nom qualifié peut être plus difficile, comme dans l’exemple suivant :

<?xml version ="1.0"?>
<Books xmlns="x-schema:bookschema.xml" >
    <Book>
        <title>Presenting XML</title>
        <author>Richard Light</author>
    </Book>
</Books>

Remarque

Aucun préfixe n’est utilisé dans les balises de nœud. Le nom qualifié doit toujours être utilisé à l’intérieur de la requête XPath, sinon la requête (par exemple, /Books/Book) ne retourne aucun résultat, car il n’existe aucun nœud correspondant.

Plus d’informations

L’exemple Visual C++ suivant est fourni pour illustrer la technique.

Pour spécifier l’espace de noms lorsque vous interrogez le DOM avec XPath, procédez comme suit :

  1. Créez un projet de console Win32 et ajoutez un nouveau fichier .cpp au projet. Collez le code suivant dans le fichier .cpp et nommez le fichier 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. Enregistrez le code XML suivant en tant que Books.xml dans le même dossier de projet que 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>
    
  3. Enregistrez le code XML suivant en tant que Bookschema.xml dans le même dossier de projet que Test.cpp.

    <?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. Compilez et exécutez l'application. Une boîte de message affiche le nombre de nœuds retournés par la XPath requête. Consultez ce qui suit :

    • Le même exemple de code peut être utilisé avec un URI explicite comme espace de noms.

    • Dans les lignes suivantes

      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");
      

      la setProperty méthode n’est pas disponible avec l’interface IXMLDOMDocument .

Un nom qualifié (QName) est composé d’un préfixe et d’une partie locale. Le préfixe fournit le préfixe d'espace de noms du nom qualifié et doit être associé à une URI d'espace de noms.

Références

Comment utiliser XPath pour interroger un espace de noms par défaut défini par l’utilisateur