Het opgeven van de naamruimte bij het opvragen van de DOM met XPath


Samenvatting


De versie van Microsoft XML Parser (MSXML) 3.0 XPath biedt een handige manier om XML-documenten opvragen en terug te keren een knooppunt of een knooppunt ingesteld. Wanneer u met de methoden selectSingleNode en selectNodes van het object IXMLDOMNode XPath-query, moet u gekwalificeerde namen. Bijvoorbeeld, selecteer het knooppunt boek met de volgende XML-gegevens
<?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>


Als we een als de alias van de x-schema:bookschema.xml Uniform Resource Identifier (URI), is de bijbehorende XPath-query als volgt:
pXMLDoc->setProperty("SelectionNamespaces","xmlns:a='x-schema:bookschema.xml'");pXMLDoc->documentElement->selectNodes("/a:Books/a:Book");

In dat geval is gebruik van de gekwalificeerde naam eenvoudig. Wanneer de standaardnaamruimte gebruikt wordt, echter zijn de gekwalificeerde naam moeilijker, zoals in het volgende voorbeeld:
<?xml version ="1.0"?><Books xmlns="x-schema:bookschema.xml" >
<Book>
<title>Presenting XML</title>
<author>Richard Light</author>
</Book>
</Books>


Houd er rekening mee dat er geen voorvoegsel wordt gebruikt in de tags knooppunt. De gekwalificeerde naam nog steeds binnen de XPath-query moet worden gebruikt, anders retourneert de query (bijvoorbeeld /Books/Book) geen resultaat omdat er geen overeenkomende knooppunten.

Meer informatie


In het volgende voorbeeld met Visual C++ is beschikbaar om aan te tonen van de techniek.

Als u de naamruimte bij het doorzoeken van de DOM met XPath, kunt u deze stappen volgen:
  1. Een console Win32-project maken en een nieuwe .cpp-bestand toevoegt aan het project. Plak de volgende code in het .cpp-bestand en de naam van het bestand 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. Het volgende XML-bestand opslaan als Books.xml in dezelfde projectmap als het 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. Het volgende XML-bestand opslaan als Bookschema.xml in dezelfde projectmap als het 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. Compileren en uitvoeren van de toepassing. Het bericht toont het aantal knooppunten dat wordt geretourneerd door de XPath-query.
Let op het volgende:
  • Dezelfde code monster kan worden gebruikt met een expliciete URI als een naamruimte.
  • In de volgende regels
    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");

    de methode setProperty is niet beschikbaar in de interface IXMLDOMDocument .
Een gekwalificeerde naam (QName) bestaat uit een voorvoegsel en een lokale gedeelte. Het voorvoegsel bevat het voorvoegsel van de naamruimte van de gekwalificeerde naam en moet worden gekoppeld aan een naamruimte-URI.

Referenties


Voor meer informatie klikt u op het volgende artikelnummer om het artikel in de Microsoft Knowledge Base:

288147 PRB: met behulp van XPath dat wordt opgevraagd ten opzichte van een standaard gebruiker gedefinieerde naamruimte