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:
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); }
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>
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>
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 dieIXMLDOMDocument
-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