XML strukturiert Daten in einigen wenigen Konstrukten, hauptsächlich in Elementen und Attributen. Die Sprache XML Path Language (XPath) definiert eine Möglichkeit, wie Teile von XML-Dokumenten für die weitere Verarbeitung selektiert werden können. XPath wird hauptsächlich von XSL Transformations (XSLT) verwendet, aber auch von anderen XML-Sprachen wie etwa XML Schema. XPath ist eine sehr kompakte Sprache mit einer Syntax, die Pfadausdrücke widerspiegelt, wie sie aus Dateisystemen wohl bekannnt sind. Diese Pfadausdrücke sind jedoch generalisiert und damit sehr viel mächtiger als die vergleichsweise einfachen Pfadausdrücke für Dateisysteme. Aufgrund ihrer Verwendung in vielen verschiedenen XML-Sprachen ist XPath eine der wichtigsten XML Sprachkomponenten.
/
. Er liefert für jedes XML-Dokument den
Wurzelknoten.
/
-Symbole separiert, notiert. Der XPath-Ausdruck
von links nach rechts gelesen spiegelt auch die
Schritte -- ausgehend vom Wurzelelement des
Dokuments -- zur Lokalisierung der gesuchten
Knotenmenge wieder.
Grundlage für das erste Beispiel zu XPath ist eine erweiterte Version der Projektverwaltung.
<?xml version="1.0" encoding="ISO-8859-15"?>
<ProjektVerwaltung xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="F:\bsz\webseite\src\vorlesung\projektverwaltung3.xsd">
<Person PersID="Pers01" mitarbeitInProjekt="Prj01">
<Vorname>Hans</Vorname>
<Nachname>Hinterhuber</Nachname>
</Person>
<Person PersID="Pers02" mitarbeitInProjekt="Prj02">
<Vorname>Franz</Vorname>
<Vorname>Xaver</Vorname>
<Nachname>Obermüller</Nachname>
<Qualifikationsprofil>
<xhtml:u>IT-Kompetenz</xhtml:u>
<xhtml:em>verschiedene</xhtml:em> Betriebssysteme und
<Leistungsstufe>professionelle</Leistungsstufe>
<xhtml:em>
<Qualifikation>Programmierung</Qualifikation>
</xhtml:em>
verschiedener Programmiersprachen
<xhtml:em>
<xhtml:u>
<Qualifikation>Entwickler</Qualifikation>
</xhtml:u>
</xhtml:em> von 1988-1990
<xhtml:u>
<Qualifikation>Projektleiterfunktion</Qualifikation>
</xhtml:u>
von <xhtml:b>1990-93</xhtml:b> im X42-Projekt in Abteilung AB&C
</Qualifikationsprofil>
</Person>
<Person PersID="Pers03" mitarbeitInProjekt="Prj02">
<Vorname>Fritz</Vorname>
<Nachname>Meier</Nachname>
<Geburtsname value="Huber"/>
</Person>
<Projekt ID="Prj01" Projektleiter="Pers01" Mitarbeiter="Pers01"/>
<Projekt ID="Prj02" Projektleiter="Pers02" Mitarbeiter="Pers03"/>
</ProjektVerwaltung>
Vorname
n selektiert, die als Kindelemente von
Person
in
ProjektVerwaltung
vorkommen.
/ProjektVerwaltung/Person/Vorname
<Vorname>Hans</Vorname>, <Vorname>Franz</Vorname>, <Vorname>Xaver</Vorname>, <Vorname>Fritz</Vorname>Anmerkung : Das Resultat ist in XML-Notation dargestellt, obwohl genaugenommen eine Knotenmenge des Information Sets als Resultat zurückgeliefert wird. Die gewählte XML-Darstellung ist hierbei nur eine der möglichen Varianten zur Ergebnispräsentation.
Qualifikation
auf derselben Baumstufe sowohl unterhalb des
Elternelements
em
als auch
u
anzutreffen.
/ProjektVerwaltung/Person/Qualifikationsprofil/*/Qualifikation
<Qualifikation>Programmierung</Qualifikation> <Qualifikation>Projektleiterfunktion</Qualifikation>
Qualifikation
-- unabhängig von der Benennung des
Elternknotens -- die direkt unterhalb des
Knotens
Qualifikationsprofil
angeordnet sind.
Qualifikation
. Der gegebene Pfadausdruck gestattet lediglich
das Überspringen
einer
Hierarchieebene. Daher wird der hierarchisch
tieferstehende Qualifikations-Knoten mit Inhalt
Entwickler nicht lokalisiert.
/ProjektVerwaltung/Person/Qualifikationsprofil/*/*/Qualifikation
zu erweitern, liefert jedoch auch nicht das
gewünschte Resultat aller
Qualifikation
s-Knoten, sondern ausschließlich den zuvor nicht
lokalisierbaren, da der neue Ausdruck nun
zwingend
zwei
freie Lokalisierungsschritte vorsieht.
//
vor. Sie erlaubt die Lokalisierung der
Kindknoten auf einer beliebigen Hierarchiestufe.
/ProjektVerwaltung/Person/Qualifikationsprofil//Qualifikation
<Qualifikation>Programmierung</Qualifikation> <Qualifikation>Entwickler</Qualifikation> <Qualifikation>Projektleiterfunktion</Qualifikation>
Ein
Lokalisierungsschritt
setzt sich aus dem Namen der
Achse
gefolgt von zwei Doppelpunkten und einem
Knotentest
, optional ergänzt um ein auszuwertendes
Prädikat
, zusammen.
Wird keine Achse spezifiziert, so gilt vorgabegemäß
die Achse
child
.
Ein Knotentest ist syntaktisch ein
QName
, der genau dann erfüllt ist, wenn der Knotenname
mit dem Namen des Knotentests übereinstimmt.
Das
Prädikat
filtert die Ergebnismenge hinsichtlich verschiedener
Charakteristika wie Existenz von Kindknoten oder
Attributen, Position in der Ergebnismenge, etc.

ancestor
,
descendant
,
following
,
preceding
und
self
partitioniert (unter Auslassung der Attribut-
und Namensraumknoten). Diese Knotenmengen
überschneiden sich nicht und enthalten alle
Elementknoten des Dokuments.
Für die einzelnen Achsen existieren darüber hinaus
auch noch Feineinstufungen.
Die folgende Tabelle listet alle durch die
Verwendung von Achsen zugänglichen Knotenmengen
relativ zum aktuellen Knoten (Knoten 8). In der
letzten Spalte ist die Knotenmenge jeweils graphisch
dargestellt. der aktuelle Knoten ist jeweils rot
markiert.
false
liefert.
Wird der folgende XPath-Ausdruck auf unser Beispiel der Projektverwaltung angewendet...
//Person[Qualifikationsprofil]/Nachname
... so erhält man folgendes Ergebnis:
<Nachname>Obermüller</Nachname>
Die einzelnen Schritte im Überblick:
Person
an beliebiger Stelle des Dokuments („//“) aus.
Qualifikationsprofil
angelegt ist. Positiv formuliert: es werden nur
diejenigen Knoten ausgewählt, die über einen
Kindknoten des Typs
Qualifikationsprofil
verfügen.
Person
!) werden dann im zweiten Lokalisierungsschritt
die Kindknoten des Typs
Nachname
ausgewählt.
Anmerkung
: Das Beispiel nutzt im Prädikat die abkürzende
Schreibweise zur Angabe der Vorgabeachse
child
. Die ausführliche Schreibweise des XPath-Ausdruckes
lautet:
//Person[child::Qualifikationsprofil]/Nachname
Das folgende Beispiel zeigt die Verwendung von
Prädikaten bei mehreren Lokalisierungsschritten.
Folgende Aufgabe soll gelöst werden:
Auswählen aller
Vorname
n als Kinder von
Person
en-Knoten, deren
Nachname
mit dem Buchstaben
O
beginnt. Weitere Einschränkung: die
Person
en-Knoten müssen ihrerseits Kinder von Knoten des
Typs
Projektverwaltung
sein.
Person
an beliebiger Stelle des Dokuments.
//Person
<Person PersID="Pers01" mitarbeitInProjekt="Prj01"> ... </Person> <Person PersID="Pers02" mitarbeitInProjekt="Prj02"> ... </Person> <Person PersID="Pers03" mitarbeitInProjekt="Prj02"> ... </Person>
Projektverwaltung
sind.
//Person[parent::ProjektVerwaltung]
<Person PersID="Pers01" mitarbeitInProjekt="Prj01"> ... </Person> <Person PersID="Pers02" mitarbeitInProjekt="Prj02"> ... </Person> <Person PersID="Pers03" mitarbeitInProjekt="Prj02"> ... </Person>
Vorname
n, die Kindelemente von
Person
sind.
//Person[parent::ProjektVerwaltung]/Vorname
<Vorname>Hans</Vorname> <Vorname>Franz</Vorname> <Vorname>Xaver</Vorname> <Vorname>Fritz</Vorname>
Nachname
folgt.
//Person[parent::ProjektVerwaltung]/Vorname[following-sibling::Nachname]
<Vorname>Hans</Vorname> <Vorname>Franz</Vorname> <Vorname>Xaver</Vorname> <Vorname>Fritz</Vorname>
starts-with
zur zusätzlichen Formulierung der Einschränkung,
daß der Nachname mit dem Buchstaben
O
beginnen muß.
//Person[parent::ProjektVerwaltung] / Vorname[starts-with(following-sibling::Nachname,'O')]
<Vorname>Franz</Vorname> <Vorname>Xaver</Vorname>
XPath-Funktionen für Knotenmengen (node-sets)
| Funktionsprototyp | Funktionalität |
|---|---|
number
last()
|
Liefert die Größe der aktuellen Knotenmenge; damit den Index des letzten Elements. |
number
position()
|
Liefert die Position des aktuellen Knotens innerhalb der Knotenmenge. Der erste Knoten trägt die Positionsnummer 1. |
number
count(
node-set
)
|
Gibt die Anzahl der Elemente der übergebenen Knotenmenge zurück. |
node-set
id(
object
)
|
Liefert denjenigen Knoten, dessen
ID-typisiertes Attribut den Argumentwert
aufweist.
Anmerkung: Zur Nutzung dieser Funktion muß zwingend eine Dokument-Grammatik (DTD oder Schema) zum Eingangsdokument vorliegen. |
string
local-name (
node-set?
)
|
Liefert den lokalen Namen (oder die Menge der Namen) der übergebenen Knotenmenge. Wird keine Knotenmenge übergeben, dann wird der aktuelle Knoten als Argument genutzt. |
string
namespace-uri (
node-set?
)
|
Gibt die Namensraum-URI der übergebenen
Knotenmenge zurück. Wird keine
Knotenmenge übergeben, dann wird der
aktuelle Knoten als Argument genutzt.
Anmerkung: Handelt es sich nicht um einen Element- oder Attributknoten, so ist die zurückgegebene Zeichenkette leer. |
string
name (
node-set?
)
|
Liefert die qualifizierten Namen
(gebildet aus Namensraumkürzel und
lokalem Namen) der übergebenen
Knotenmenge, oder des aktuellen Knotens
bei leerer Knotenmenge.
Anmerkung: Nur für Element- und Attributknoten liefert name
andere Resultate als
local-name
.
|
XPath-Funktionen für Zeichenketten
| Funktionsprototyp | Funktionalität |
|---|---|
string
string (
object?
)
|
Liefert Zeichenkettenrepräsentation einer Knotenmenge. Dabei wird der Zeichenkettenwert des ersten Knotens in der Dokumentreihenfolge zurückgegeben, andernfalls die leere Zeichenkette. |
string
concat (
string
,
string
,
string*
)
|
Verkettet mindestens zwei Zeichenketten. |
boolean
starts-with (
string1
,
string2
)
|
Liefert
true
, falls
string1
das zweite Argument
string2
als Präfix enthält; andernfalls
false
.
|
boolean
contains (
string1
,
string2
)
|
Liefert
true
falls
string1
die Zeichenkette aus
string2
enthält; andernfalls
false
.
|
string
substring-before (
string1
,
string2
)
|
Liefert denjenigen Teil der Zeichenkette
string1
, der sich vor dem ersten Auftreten der
Zeichenkette
string2
befindet.
|
string
substring-after (
string1
,
string2
)
|
Liefert denjenigen Teil der Zeichenkette
string1
, der sich nach dem ersten Auftreten der
Zeichenkette
string2
befindet.
|
string
substring (
string
,
number1
,
number2?
)
|
Liefert eine Zeichenkette der Länge
number2
aus
string
, beginnend mit der Position
number1
. Fehlt das dritte Argument, so wird der
Teilstring bis zum Ende der Zeichenkette
string
zurückgegeben.
Anmerkung: Das erste Zeichen trägt die Indexnummer 1, nicht 0 wie in Java und C üblich. |
number
string-length(
string?
)
|
Liefert die Länge der übergebenen Zeichenkette. Wird kein Argument übergeben, so wird die Länge des zuvor in eine Zeichenkette konvertierten aktuellen Knotens zurückgegeben. |
string
normalize-space (
string?
)
|
Liefert die übergebene Zeichenkette
unter Entfernung führender, schließender
und mehrfacher Leerzeichen zurück.
Ferner werden noch evtl. in der
Argumentzeichenkette enthaltenen
Entitätsreferenzen aufgelöst.
Anmerkung: Der Normalisierungsvorgang entspricht damit der Attributwertenormalisierung nach Abschnitt 3.3.3 der XML-Spezifikation . |
string
translate (
string1
,
string2
,
string3
)
|
Liefert die Zeichenkette
string1
, wobei jedes Zeichen aus
string2
durch das Zeichen an derselben Position
aus
string3
ersetzt wurde.
|
Boole'sche XPath-Funktionen
| Funktionsprototyp | Funktionalität |
|---|---|
boolean
boolean (
object
)
|
Liefert die Boole'sche Repräsentation
des übergebenen Arguments.
Hierbei gilt:
|
boolean
not (
boolean
)
|
Negiert das übergebene Argument. |
boolean
true()
|
Liefert statisch den Wert
true
.
|
boolean
false()
|
Liefert statisch den Wert
false
.
|
boolean
lang (
string
)
|
Liefert
true
, wenn der aktuelle Knoten ein
xml:lang
-Attribut gemäß der als Argument
übergebenen Sprache besitzt.
|
Zahlenorientierte XPath-Funktionen
| Funktionsprototyp | Funktionalität |
|---|---|
number
number (
object?
)
|
Konvertiert ein Objekt in eine Zahl
gemäß folgender Regeln:
|
number
sum (
node-set
)
|
Liefert die Summe aller Elemente der übergebenen Knotenmenge, die zuvor in eine Zahl konvertiert werden. |
number
floor (
number
)
|
Liefert die größte ganze Zahl, die nicht
größer als das Argument ist.
Beispiele: floor(7.4)=7
,
floor(−5)=−5
und
floor(−5.4)=−6
.
|
number
ceiling (
number1
)
|
Liefert die kleinste ganze Zahl, die
nicht kleiner als das Argument ist.
Beispiele: ceiling(7.4)=8
,
ceiling(−5)=−5
und
ceiling(−5.4)=−5
.
|
number
round (
number
)
|
Liefert das Argument auf die nächste
ganze Zahl gerundet. Gibt es zwei solche
-- wie bei Nachkommastelle gleich
0.5
immer der Fall -- so wird die größere
zurückgeliefert.
|
Mathematische Operatoren
| Funktionsprototyp | Funktionalität |
|---|---|
+
|
Addition |
-
|
Subtraktion
Anmerkung: Weil XML in Elementnamen den Bindestrich erlaubt, muß dieser Operator in einem Ausdruck immer durch Leerzeichen von den Operanden getrennt werden, andernfalls wird der gesamte Ausdruck als Name gewertet. |
*
|
Multiplikation
Außer wenn innerhalb von XPath-Ausdrücken als Knotentest eingesetzt. |
div
|
Division
Achtung: Das Symbol /
dient ausschließlich als Trennzeichen
innerhalb Lokalisierungspfaden!
|
mod
|
Modulo
Rest einer ganzzahligen Division. Beispiel: 5 mod 2
ergibt
1
und
-5 mod 2
ergibt
-1
.
|
Folgende Aufgabe soll gelöst werden:
Welchen Knoten im Dokument lokalisiert folgender
XPath-Ausdruck:
//Person[count(Vorname)=1]/ Nachname[following-sibling::Geburtsname[@value]]/ parent::Person/@mitarbeitInProjekt
Schrittweises Nachverfolgen der einzelnen Lokalisierungsschritte und Filterungen:
Person
en an beliebiger Stelle des Dokuments:
//Person
<Person PersID="Pers01" mitarbeitInProjekt="Prj01"> ... </Person> <Person PersID="Pers02" mitarbeitInProjekt="Prj02"> ... </Person> <Person PersID="Pers03" mitarbeitInProjekt="Prj02"> ... </Person>
Person
en, die genau einen Kindknoten
Vorname
besitzen
//Person[count(Vorname)=1]
<Person PersID="Pers01" mitarbeitInProjekt="Prj01"> ... </Person> <Person PersID="Pers03" mitarbeitInProjekt="Prj02"> ... </Person>
Nachname
jeder ausgewählten Person
//Person[count(Vorname)=1]/Nachname
<Nachname>Hinterhuber</Nachname> <Nachname>Meier</Nachname>
Nachname
n auf diejenigen, die einen nachfolgenden
Geschwisterknoten vom Typ
Geburtsname
besitzen.
//Person[count(Vorname)=1]/Nachname[following-sibling::Geburtsname]
<Nachname>Meier</Nachname>
Nachname
n auf diejenigen, die einen nachfolgenden
Geschwisterknoten vom Typ
Geburtsname
mit einem Attribut namens
value
besitzt (Test auf Existenz!).
//Person[count(Vorname)=1]/Nachname[following-sibling::Geburtsname[@value]]
<Nachname>Meier</Nachname>
Person
.
//Person[count(Vorname)=1]/Nachname[following-sibling::Geburtsname[@value]]/ parent::Person
<Person PersID="Pers03" mitarbeitInProjekt="Prj02"> ... </Person>
Person
der eben selektierten Menge, navigiere zum
Attributknoten
mitarbeitInProjekt
.
//Person[count(Vorname)=1]/Nachname[following-sibling::Geburtsname[@value]]/ parent::Person/@mitarbeitInProjekt
mitarbeitInProjekt="Prj02"
Der XPath-Ausdruck lokalisiert den Attributknoten
mitarbeitInProjekt
von Person 3 mit dem Wert
Prj02
.
Welches Ergebnis liefern folgende XPath-Ausdrücke?
//Person[//child::Qualifikationsprofil]/Nachname
//Person[parent::ProjektVerwaltung]/Vorname[following-sibling::Vorname]
/ProjektVerwaltung/Person[attribute::PersID='Pers01']//Nachname
ID
und
IDREF
,
IDREFS
-Konstrukte aus der DTD in Schema übernommen
wurden (Gültigkeit von Referenzen auf das
aktuelle Dokument beschränkt, damit sind
dokumentweit eindeutige Bezeichner notwendig).
unique
-Element.
selector
), und zur Angabe der eingeschränkten Knoten (
field
) selbst.
<xsd:unique name="aName"> <xsd:selector xpath="aValidXPath"/> <xsd:field xpath="aFieldStatement"/> ... </xsd:unique>
selector
-Element: es sind hier nur Ausdrücke erlaubt,
die Kindelemente des Knotens liefern, in dessen
Kontext die Einschränkung mittels des
unique
-Elements angegeben wird.
field
-Elementen werden relativ zum Pfad des
selector
-Knotens interpretiert.
selector
-Elements, gefolgt von einem Pfad eines
field
-Elements, einen gültigen Lokationsausdruck
ergeben, der genau einen Knoten oder genau ein
Attribut in der Ergebnismenge liefert.
field
-Elemente zu einem
selector
-Element gegeben, so werden diese als durch
logisches und verknüpft interpretiert.
Im folgenden Beispiel wird das
unique
-Element verwendet, um zu formulieren, daß das
Attribut
PersID
des Elements
Person
eindeutig sein muß (dies entspricht -- noch -- der
bisherigen ID-Typisierung).
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:element name="ProjektVerwaltung"> <xsd:complexType> <xsd:sequence> <xsd:element name="Person" type="PersonType" maxOccurs="unbounded"/> <xsd:element name="Projekt" type="ProjektType" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute name="version" type="xsd:string" fixed="1.0"/> </xsd:complexType> <xsd:unique name="uniquenessPersID"> <xsd:selector xpath="Person"/> <xsd:field xpath="@PersID"/> </xsd:unique> </xsd:element> <xsd:complexType name="PersonType"> <xsd:attribute name="PersID" type="xsd:token"/> </xsd:complexType> <xsd:complexType name="ProjektType"/> </xsd:schema>
/Person
wählt zunächst alle Knoten des gleichnamigen
Typs aus.
field
-Element wendet die Eindeutigkeitsbedingung auf
alle Attribut-Kindnoten des Typs
PersID
der Knoten in der selektierten Knotenmenge (
/Person
) an.
Das nächste Beispiel zeigt die Verwendung
mehrerer
field
-
Elemente
zur Realisierung zusammengesetzter Schlüssel.
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified"> <xsd:element name="ProjektVerwaltung"> <xsd:complexType> <xsd:sequence> <xsd:element name="Person" type="PersonType" maxOccurs="unbounded"/> <xsd:element name="Projekt" type="ProjektType" maxOccurs="unbounded"/> </xsd:sequence> <xsd:attribute name="version" type="xsd:string" fixed="1.0"/> </xsd:complexType> <xsd:unique name="uniquenessPersID"> <xsd:selector xpath="Person"/> <xsd:field xpath="Vorname"/> <xsd:field xpath="Nachname"/> </xsd:unique> </xsd:element> <xsd:complexType name="PersonType"> <xsd:sequence> <xsd:element name="Vorname" type="xsd:token" minOccurs="1" maxOccurs="unbounded"/> <xsd:element name="Nachname" type="xsd:token" maxOccurs="1"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="ProjektType"/> </xsd:schema>
Nachname
n- und des
Vorname
n-Elements zusammen wird als eindeutig
deklariert.
Mit Hilfe der XML-Schema-Elemente
key
und
keyref
ist es möglich, Referenzen auf bestimmte
Referenzmengen einzuschränken. Hiermit kann
sichergestellt werden, daß als Werte eines Attributs
mitarbeitInProjekt
auch wirklich nur auf Schlüssel verwiesen werden
kann, die für ein Projekt definiert wurden. Damit
ist es im Gegensatz zu DTDs nicht mehr möglich, an
dieser Stelle auf IDs von Personen zu verweisen.
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:element name="ProjektVerwaltung">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Person" type="PersonType" maxOccurs="unbounded"/>
<xsd:element name="Projekt" type="ProjektType" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="version" type="xsd:string" fixed="1.0"/>
</xsd:complexType>
<xsd:key name="projectKey">
<xsd:selector xpath="Projekt"/>
<xsd:field xpath="@ID"/>
</xsd:key>
<xsd:keyref name="projectReference" refer="projectKey">
<xsd:selector xpath="Person"/>
<xsd:field xpath="@mitarbeitInProjekt"/>
</xsd:keyref>
</xsd:element>
<xsd:complexType name="PersonType">
<xsd:attribute name="mitarbeitInProjekt" type="xsd:token"/>
</xsd:complexType>
<xsd:complexType name="ProjektType">
<xsd:attribute name="ID" type="xsd:token"/>
</xsd:complexType>
</xsd:schema>projectKey
benannte Schlüssel (
key
) definiert die Referenzmenge als das Ergebnis
der XPath-Ausdruckes
Projekt/@ID
projectReference
mittels
refer="projectKey"
Bezug. In einer durch
keyref
lokalisierten Knotenmenge dürfen ausschließlich
Elemente der Referenzmenge enthalten sein.
ID/IDREF
Zusammenfassend lassen sich folgende Vorteile
gegenüber dem
ID/IDREF
-Mechanismus festhalten: