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 d’origine du produit : Microsoft XML Parser
Numéro de la base de connaissances d’origine : 294797

Résumé

Avec la version XPath 3.0 de l’analyseur XML (MSXML), fournit un moyen pratique d’interroger des documents XML et de retourner un nœud ou un ensemble de nœuds. Lorsque vous utilisez XPath la requête avec les selectSingleNode méthodes 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 un 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é dans la requête XPath, sinon la requête (par exemple, /Books/Book) ne retourne aucun résultat, car il n’y a pas de nœuds correspondants.

Informations supplémentaires

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 sous 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 sous 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é à un URI d’espace de noms.

References

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