Angeben des Namespace beim Abfragen des DOM mit XPath

In diesem Artikel wird beschrieben, dass Sie qualifizierte Namen verwenden müssen, wenn Sie die XPath-Abfrage mit den methoden selectSingleNode und selectNodes des IXMLDOMNode Objekts verwenden.

Ursprüngliche Produktversion: Microsoft XML Parser
Ursprüngliche KB-Nummer: 294797

Zusammenfassung

Mit dem XML Parser (MSXML) 3.0-Release bietet eine bequeme Möglichkeit, XPath XML-Dokumente abzufragen und einen Knoten oder knotensatz zurückzugeben. Wenn Sie die Abfrage mit den selectSingleNode Methoden und selectNodes des IXMLDOMNode Objekts verwendenXPath, müssen Sie qualifizierte Namen verwenden. So wählen Sie beispielsweise den Knoten Buch mit den folgenden XML-Daten aus:

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

Wenn wir einen als Alias des x-schema:bookschema.xml URI (Uniform Resource Identifier) verwenden, lautet die entsprechende XPath-Abfrage wie folgt:

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

In diesem Fall ist die Verwendung des qualifizierten Namens einfach. Wenn der Standardnamespace verwendet wird, kann die Verwendung des qualifizierten Namens jedoch schwieriger sein, wie im folgenden Beispiel gezeigt:

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

Hinweis

In den Knotentags wird kein Präfix verwendet. Der qualifizierte Name muss weiterhin innerhalb der XPath-Abfrage verwendet werden, andernfalls gibt die Abfrage (z. B. /Books/Book) kein Ergebnis zurück, da keine übereinstimmenden Knoten vorhanden sind.

Weitere Informationen

Das folgende Visual C++-Beispiel wird bereitgestellt, um die Technik zu veranschaulichen.

Führen Sie die folgenden Schritte aus, um den Namespace anzugeben, wenn Sie das DOM mit XPath abfragen:

  1. Erstellen Sie ein Win32-Konsolenprojekt, und fügen Sie dem Projekt eine neue .cpp-Datei hinzu. Fügen Sie den folgenden Code in die .cpp-Datei ein, und benennen Sie die Datei 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. Speichern Sie den folgenden XML-Code als Books.xml im selben Projektordner wie 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. Speichern Sie den folgenden XML-Code als Bookschema.xml im selben Projektordner wie 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. Kompilieren Sie die Anwendung, und führen Sie sie aus. Ein Meldungsfeld zeigt die Anzahl der Knoten an, die von der XPath Abfrage zurückgegeben werden. Siehe hierzu:

    • Der gleiche Beispielcode kann mit einem expliziten URI als Namespace verwendet werden.

    • In den folgenden Zeilen

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

      Die setProperty -Methode ist für die IXMLDOMDocument -Schnittstelle nicht verfügbar.

Ein qualifizierter Name (QName) besteht aus einem Präfix und einem lokalen Teil. Das Präfix stellt das Namespacepräfix des qualifizierten Namens bereit und muss einem Namespace-URI zugeordnet sein.

References

Verwenden von XPath zum Abfragen für einen benutzerdefinierten Standardnamespace