Share via


Abfragen von XML mithilfe von OPENXML

OPENXML ist ein Transact-SQL-Schlüsselwort, das für arbeitsspeicherinterne XML-Dokumente ein Rowset bereitstellt, das mit einer Tabelle oder einer Sicht vergleichbar ist. OPENXML ermöglicht es, auf XML-Daten so zuzugreifen, wie auf ein relationales Rowset. Dies geschieht, indem eine Rowsetsicht der internen Darstellung eines XML-Dokuments bereitgestellt wird. Die Datensätze im Rowset können in Datenbanktabellen gespeichert werden.

OPENXML kann immer dann in SELECT- und SELECT INTO-Anweisungen verwendet werden, wenn Rowsetanbieter, eine Sicht oder OPENROWSET als Quelle verwendet werden können. Information zu der OPENXML-Syntax finden Sie unter OPENXML (Transact-SQL).

Um Abfragen für XML-Dokumente mithilfe von OPENXML zu schreiben, müssen Sie zunächst sp_xml_preparedocument aufrufen. Dies analysiert das XML-Dokument und gibt ein Handle auf das analysierte Dokument zurück, das zur Verwendung bereit ist. Das analysierte Dokument ist eine strukturierte Dokumentobjektdarstellung (DOM - Document Object Model) der verschiedenen Knoten des XML-Dokuments. Das Dokumenthandle wird an OPENXML übergeben. OPENXML erstellt dann auf der Grundlage der übergebenen Parameter eine Rowsetsicht des Dokuments.

HinweisHinweis

Ab SQL Server 2005 verwendet sp_xml_preparedocument eine SQL-aktualisierte Version des MSXML-Parsers (Msxmlsql.dll). Diese Version des MSXML-Parsers wurde für SQL Server entwickelt und ist abwärtskompatibel zu MSXML Version 2.6.

Um den Arbeitsspeicher zu leeren, muss die interne Darstellung eines XML-Dokuments durch einen Aufruf der gespeicherten Systemprozedur sp_xml_removedocument aus dem Arbeitsspeicher gelöscht werden.

Der Vorgang wird in der folgenden Abbildung veranschaulicht.

Analysieren von XML mit OPENXML

Um die Funktionsweise von OPENXML zu verstehen, benötigen Sie Kenntnisse über XPath-Abfragen und XML. Weitere Informationen zur XPath-Unterstützung in SQL Server finden Sie unter Verwenden von XPath-Abfragen in SQLXML 4.0.

HinweisHinweis

Mit OpenXML können die XPath-Muster für die Zeilen und Spalten als Variablen parametrisiert werden. Diese Art der Parametrisierung kann zu XPath-Ausdrucksangriffen führen, wenn der Programmierer die Parametrisierung für externe Benutzer offen legt (wenn Parameter beispielsweise über eine extern aufgerufene gespeicherte Prozedur bereitgestellt werden). Um solche potenziellen Sicherheitsprobleme zu vermeiden, sollten XPath-Parameter niemals für externe aufrufende Prozesse offen gelegt werden.

OPENXML-Parameter

Zu den Parametern für OPENXML gehören:

  • Ein XML-Dokumenthandle (idoc)

  • Ein XPath-Ausdruck zur Identifizierung der Knoten, die Zeilen zugeordnet werden (rowpattern)

  • Eine Beschreibung des zu generierenden Rowsets

  • Die Zuordnung zwischen den Rowsetspalten und den XML-Knoten

XML-Dokumenthandle (idoc)

Das Dokumenthandle wird von der gespeicherten Prozedur sp_xml_preparedocument zurückgegeben.

XPath-Ausdruck zur Identifizierung der zu verarbeitenden Knoten (rowpattern)

Der als rowpattern angegebene XPath-Ausdruck bezeichnet einen Knotensatz im XML-Dokument. Jeder von rowpattern identifizierte Knoten entspricht in dem von OPENXML generierten Rowset einer einzelnen Zeile.

Bei den durch den XPath-Ausdruck identifizierten Knoten kann es sich um jeden im XML-Dokument enthaltenen Knoten handeln. Wenn rowpattern eine Reihe von Elementen im XML-Dokument identifiziert, wird für jeden identifizierten Elementknoten eine Zeile im Rowset erstellt. Wenn z. B. rowpattern mit einem Attribut endet, wird für jeden von rowpattern ausgewählten Attributknoten eine Zeile erstellt.

Beschreibung des zu generierenden Rowsets

Zum Generieren des Rowsets verwendet OPENXML ein Rowsetschema. Ein Rowsetschema kann über die folgenden Optionen angegeben werden.

Verwenden des Rahmentabellenformats

Um ein Rowsetschema anzugeben, müssen Sie das Rahmentabellenformat verwenden. Verwenden Sie keine WITH-Klausel.

In diesem Fall gibt OPENXML ein Rowset im Rahmentabellenformat zurück. Die Bezeichnung Rahmentabelle geht darauf zurück, dass jeder Rahmen in der analysierten XML-Dokumentstruktur einer Zeile im Rowset zugeordnet wird.

Rahmentabellen stellen die detaillierte XML-Dokumentstruktur in einer einzigen Tabelle dar. Diese Struktur enthält die Element- und Attributnamen, die Dokumenthierarchie, die Namespaces und die Verarbeitungsanweisungen. Durch das Rahmentabellenformat erhalten Sie zusätzliche Informationen, die nicht über die Metaeigenschaften offen gelegt werden. Weitere Informationen über Metaeigenschaften finden Sie unter Specifying Metaproperties in OPENXML29bfd1c6-3f9a-43c4-924a-53d438e442f4.

Die von Rahmentabellen gebotenen zusätzlichen Informationen ermöglichen Ihnen das Speichern und Abfragen des Datentyps eines Elements oder Attributs, des Knotentyps sowie das Speichern und Abfragen von Informationen zur Struktur von XML-Dokumenten. Die zusätzlichen Informationen ermöglichen außerdem das Erstellen eines eigenen XML-Dokumentmanagementsystems.

Mithilfe einer Rahmentabelle können Sie gespeicherte Prozeduren schreiben, die XML-Dokumente als BLOB-Eingabe (Binary Large OBject) verwenden, die Rahmentabelle ausgeben und dann das Dokument auf einer detaillierteren Ebene extrahieren und analysieren. Diese detaillierte Ebene kann die Dokumenthierarchie, die Element- und Attributnamen, die Namespaces und die Verarbeitungsanweisungen enthalten.

Die Rahmentabelle kann auch als Speicherformat für XML-Dokumente dienen, wenn keine andere Zuordnung zu relationalen Formaten logisch ist und ein ntext-Feld keine ausreichenden strukturellen Informationen bietet.

Wenn die Überprüfung des XML-Dokuments mit einem XML-Parser möglich ist, können Sie dieselben Informationen stattdessen auch mit einer Rahmentabelle erhalten.

In der folgenden Tabelle wird die Struktur der Rahmentabelle beschrieben.

Spaltenname

Datentyp

Beschreibung

id

bigint

Die eindeutige ID des Dokumentknotens.

Das Stammelement weist den ID-Wert 0 auf. Die negativen ID-Werte sind reserviert.

parentid

bigint

Identifiziert das übergeordnete Objekt des Knotens. Bei dem über diese ID identifizierten übergeordneten Objekt muss es sich nicht unbedingt um das übergeordnete Element handeln. Dies hängt jedoch vom NodeType des Knotens ab, dessen übergeordnetes Objekt durch diese ID identifiziert wird. Wenn es sich bei dem Knoten beispielsweise um einen Textknoten handelt, kann das übergeordnete Objekt ein Attributknoten sein.

Wenn sich der Knoten auf der obersten Ebene im XML-Dokument befindet, ist ParentID gleich NULL.

node type

int

Identifiziert den Knotentyp. Eine ganze Zahl, die der Nummer des Knotentyps des XML-Objektmodells (DOM) entspricht.

In dieser Spalte können folgende Werte den Knotentyp angeben:

1 = Elementknoten

2 = Attributknoten

3 = Textknoten

4 = CDATA-Abschnittsknoten

5 = Entitätsverweisknoten

6 = Entitätsknoten

7 = Verarbeitungsanweisungsknoten

8 = Kommentarknoten

9 = Dokumentknoten

10 = Dokumenttypknoten

11 = Dokumentfragmentknoten

12 = Notationsknoten

Weitere Informationen finden Sie im Microsoft XML (MSXML) SDK im Abschnitt über die nodeType-Eigenschaft.

localname

nvarchar(max)

Der lokale Name des Elements oder Attributs. Ist NULL, wenn das DOM-Objekt keinen Namen hat.

Präfix

nvarchar(max)

Das Namespacepräfix des Knotennamens.

namespaceuri

nvarchar(max)

Der Namespace-URI (Universal Resource Identifier) des Knotens. Ist der Wert NULL, ist kein Namespace vorhanden.

datatype

nvarchar(max)

Der eigentliche Datentyp der Element- oder Attributzeile, der anderenfalls NULL ist. Der Datentyp wird aus der Inline-DTD (Document Type Definition) oder aus dem Inlineschema abgeleitet.

prev

bigint

Die XML-ID des vorhergehenden gleichgeordneten Elements. Ist NULL, wenn kein direktes vorhergehendes gleichgeordnetes Element vorhanden ist.

text

ntext

Enthält den Attributwert oder den Elementinhalt als Text. Oder ist NULL, wenn für den Rahmentabelleneintrag kein Wert benötigt wird.

Verwenden der WITH-Klausel, um eine vorhandene Tabelle anzugeben

Mit der WITH-Klausel können Sie den Namen einer vorhandenen Tabelle angeben. Hierzu geben Sie einfach den Namen einer vorhandenen Tabelle an, deren Schema OPENXML zum Generieren des Rowsets verwenden kann.

Verwenden der WITH-Klausel, um ein Schema anzugeben

Mit der WITH-Klausel können Sie ein vollständiges Schema angeben. Ein Rowsetschema wird durch Angeben der Spaltennamen, der zugehörigen Datentypen und der Zuordnung zum XML-Dokument angegeben.

Sie können das Spaltenmuster mithilfe des ColPattern-Parameters in SchemaDeclaration angeben. Das angegebene Spaltenmuster wird zur Zuordnung einer Rowsetspalte zum von rowpattern bezeichneten XML-Knoten und zur Bestimmung des Zuordnungstyps verwendet.

Wenn ColPattern für eine Spalte nicht angegeben ist, wird die Rowsetspalte basierend auf der vom flags-Parameter angegebenen Zuordnung dem XML-Knoten mit demselben Namen zugeordnet. Wenn ColPattern in der WITH-Klausel jedoch als Teil der Schemaspezifikation angegeben ist, wird die im flags-Parameter angegebene Zuordnung überschrieben.

Zuordnung zwischen den Rowsetspalten und den XML-Knoten

In der OPENXML-Anweisung können Sie optional den Typ der Zuordnung – wie attributzentriert, elementzentriert – zwischen den Rowsetspalten und den von rowpattern identifizierten XML-Knoten angeben. Diese Information wird bei der Transformation zwischen XML-Knoten und Rowsetspalten verwendet.

Die Zuordnung kann auf zwei Arten angegeben werden, wobei Sie auch beide angeben können:

  • Mit dem flags-Parameter

    Die vom flags-Parameter angegebene Zuordnung geht von einer Namensentsprechung aus, bei der die XML-Knoten den entsprechenden Rowsetspalten mit demselben Namen zugeordnet werden.

  • Mit dem ColPattern-Parameter

    ColPattern, ein XPath-Ausdruck, wird in der WITH-Klausel als Teil von SchemaDeclaration angegeben. Durch die in ColPattern angegebene Zuordnung wird die Zuordnung des flags-Parameters überschrieben.

    ColPattern kann zur Angabe des Zuordnungstyps – wie attributzentriert oder elementzentriert – verwendet werden, der die vom flags-Parameter angegebene Standardzuordnung überschreibt oder erweitert.

    ColPattern wird in folgenden Situationen angegeben:

    • Der Spaltenname im Rowset unterscheidet sich vom Element- oder Attributnamen, dem er zugeordnet ist. In diesem Fall wird ColPattern zur Identifizierung des XML-Element- und Attributnamens verwendet, dem die Rowsetspalte zugeordnet ist.

    • Der Spalte soll ein Metaeigenschaftsattribut zugeordnet werden. In diesem Fall wird ColPattern zur Identifizierung der Metaeigenschaft verwendet, der die Rowsetspalte zugeordnet ist. Weitere Informationen zur Verwendung von Metaeigenschaften finden Sie unter Angeben von Metaeigenschaften in OPENXML.

Sowohl der flags-Parameter als auch der ColPattern-Parameter sind optional. Wenn keine Zuordnung angegeben ist, wird eine attributzentrierte Zuordnung vorgenommen. Die attributzentrierte Zuordnung ist der Standardwert des flags-Parameters.

Attributzentrierte Zuordnung

Wenn der flags-Parameters in OPENXML auf 1 festgelegt ist (XML_ATTRIBUTES), wird die attributzentrierte Zuordnung durchgeführt. Wenn flags XML_ ATTRIBUTES enthält, enthält oder verwendet das verfügbar gemachte Rowset Zeilen, in denen jedes XML-Element als eine Zeile dargestellt ist. Die XML-Attribute werden anhand ihres Namens den Attributen zugeordnet, die in SchemaDeclaration definiert sind, oder die in der WITH-Klausel über Tablename bereitgestellt werden. Die Namensübereinstimmung bedeutet, dass XML-Attribute eines bestimmten Namens in einer Spalte im Rowset mit demselben Namen gespeichert werden.

Wenn sich der Spaltenname vom zugeordneten Attributnamen unterscheidet, muss der ColPattern-Parameter angegeben werden.

Wenn das XML-Attribut über einen Namespacequalifizierer verfügt, muss der Spaltenname im Rowset ebenfalls über einen Qualifizierer verfügen.

Elementzentrierte Zuordnung

Wenn der flags-Parameters in OPENXML auf 2 (XML_ELEMENTS) festgelegt ist, wird die elementzentrierte Zuordnung vorgenommen. Sie ist, abgesehen von den folgenden Unterschieden, mit der attributzentrierten Zuordnung vergleichbar:

  • Die Namensübereinstimmung der Zuordnung (z. B. eine Spaltenzuordnung zu einem XML-Element desselben Namens) wählt die nicht komplexen Teilelemente aus, es sei denn, es wurde ein Muster auf Spaltenebene angegeben. Wenn das Teilelement komplex ist, weil es weitere Teilelemente enthält, wird die Spalte während des Abfrageprozesses auf NULL festgelegt. Attributwerte der Teilelemente werden dann ignoriert.

  • Wenn mehrere Teilelemente denselben Namen besitzen, wird der erste Knoten zurückgeliefert.