Freigeben über


Ändern von XML-Daten mithilfe von XPathNavigator

Die XPathNavigator Klasse stellt eine Reihe von Methoden bereit, die zum Ändern von Knoten und Werten in einem XML-Dokument verwendet werden. Um diese Methoden verwenden zu können, muss das XPathNavigator Objekt bearbeitbar sein, d. h. seine CanEdit Eigenschaft muss sein true.

XPathNavigator Objekte, die ein XML-Dokument bearbeiten können, werden von der CreateNavigator Methode der XmlDocument Klasse erstellt. XPathNavigator von der XPathDocument Klasse erstellte Objekte sind schreibgeschützt und jeder Versuch, die Bearbeitungsmethoden eines XPathNavigator-Objekts zu verwenden, das durch ein XPathDocument-Objekt erstellt wurde, resultiert in einem NotSupportedException.

Weitere Informationen zum Erstellen bearbeitbarer XPathNavigator Objekte finden Sie unter Lesen von XML-Daten mit XPathDocument und XmlDocument.

Ändern von Knoten

Eine einfache Technik zum Ändern des Werts eines Knotens besteht darin, die SetValue Methoden und SetTypedValue Methoden der XPathNavigator Klasse zu verwenden.

In der folgenden Tabelle sind die Auswirkungen dieser Methoden auf verschiedene Knotentypen aufgeführt.

XPathNodeType Geänderte Daten
Root Nicht unterstützt.
Element Der Inhalt des Elements.
Attribute Der Wert des Attributs.
Text Der Textinhalt.
ProcessingInstruction Der Inhalt, mit Ausnahme des Ziels.
Comment Der Inhalt des Kommentars.
Namespace Nicht unterstützt.

Hinweis

Das Bearbeiten von Namespace Knoten oder der Root Knoten wird nicht unterstützt.

Die XPathNavigator Klasse stellt auch eine Reihe von Methoden bereit, die zum Einfügen und Entfernen von Knoten verwendet werden. Weitere Informationen zum Einfügen und Entfernen von Knoten aus einem XML-Dokument finden Sie in den Themen zum Einfügen von XML-Daten mit XPathNavigator und Zum Entfernen von XML-Daten mit XPathNavigator .

Ändern nicht eingegebener Werte

Die SetValue Methode fügt einfach den nicht typisierten string Wert ein, der als Parameter übergeben wird, als Wert des Knotens, auf dem das XPathNavigator Objekt aktuell positioniert ist. Der Wert wird ohne Typ oder ohne Überprüfung der Gültigkeit des neuen Werts gemäß dem Typ des Knotens eingefügt, wenn Schemainformationen verfügbar sind.

Im folgenden Beispiel wird die SetValue Methode verwendet, um alle price Elemente in der contosoBooks.xml Datei zu aktualisieren.

XmlDocument document = new XmlDocument();
document.Load("contosoBooks.xml");
XPathNavigator navigator = document.CreateNavigator();

XmlNamespaceManager manager = new XmlNamespaceManager(navigator.NameTable);
manager.AddNamespace("bk", "http://www.contoso.com/books");

foreach (XPathNavigator nav in navigator.Select("//bk:price", manager))
{
    if (nav.Value == "11.99")
    {
        nav.SetValue("12.99");
    }
}

Console.WriteLine(navigator.OuterXml);
Dim document As XmlDocument = New XmlDocument()
document.Load("contosoBooks.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()

Dim manager As XmlNamespaceManager = New XmlNamespaceManager(navigator.NameTable)
manager.AddNamespace("bk", "http://www.contoso.com/books")

For Each nav As XPathNavigator In navigator.Select("//bk:price", manager)
    If nav.Value = "11.99" Then
        nav.SetValue("12.99")
    End If
Next

Console.WriteLine(navigator.OuterXml)

Im Beispiel wird die contosoBooks.xml Datei als Eingabe verwendet.

<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
        <title>The Autobiography of Benjamin Franklin</title>
        <author>
            <first-name>Benjamin</first-name>
            <last-name>Franklin</last-name>
        </author>
        <price>8.99</price>
    </book>
    <book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
        </author>
        <price>11.99</price>
    </book>
    <book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <author>
            <name>Plato</name>
        </author>
        <price>9.99</price>
    </book>
</bookstore>

Ändern von typierten Werten

Wenn der Typ eines Knotens ein einfacher W3C-XML-Schematyp ist, wird der neue Wert, der von der SetTypedValue Methode eingefügt wird, anhand der Facets des einfachen Typs überprüft, bevor der Wert festgelegt wird. Wenn der neue Wert nicht gemäß dem Typ des Knotens gültig ist (z. B. festlegen eines Werts -1 für ein Element, dessen Typ ist xs:positiveInteger), führt er zu einer Ausnahme.

Im folgenden Beispiel wird versucht, den Wert des price Elements des ersten book Elements in der contosoBooks.xml Datei in einen DateTime Wert zu ändern. Da der XML-Schematyp des price Elements wie xs:decimal in den contosoBooks.xsd Dateien definiert ist, führt dies zu einer Ausnahme.

Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")
settings.ValidationType = ValidationType.Schema

Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)

Dim document As XmlDocument = New XmlDocument()
document.Load(reader)
Dim navigator As XPathNavigator = document.CreateNavigator()

navigator.MoveToChild("bookstore", "http://www.contoso.com/books")
navigator.MoveToChild("book", "http://www.contoso.com/books")
navigator.MoveToChild("price", "http://www.contoso.com/books")

navigator.SetTypedValue(DateTime.Now)
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");
settings.ValidationType = ValidationType.Schema;

XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);

XmlDocument document = new XmlDocument();
document.Load(reader);
XPathNavigator navigator = document.CreateNavigator();

navigator.MoveToChild("bookstore", "http://www.contoso.com/books");
navigator.MoveToChild("book", "http://www.contoso.com/books");
navigator.MoveToChild("price", "http://www.contoso.com/books");

navigator.SetTypedValue(DateTime.Now);

Im Beispiel wird die contosoBooks.xml Datei als Eingabe verwendet.

<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
        <title>The Autobiography of Benjamin Franklin</title>
        <author>
            <first-name>Benjamin</first-name>
            <last-name>Franklin</last-name>
        </author>
        <price>8.99</price>
    </book>
    <book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
        </author>
        <price>11.99</price>
    </book>
    <book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <author>
            <name>Plato</name>
        </author>
        <price>9.99</price>
    </book>
</bookstore>

Im Beispiel wird auch contosoBooks.xsd als Eingabe verwendet.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="bookstore">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="book">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="title" type="xs:string" />
                            <xs:element name="author">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element minOccurs="0" name="name" type="xs:string" />
                                        <xs:element minOccurs="0" name="first-name" type="xs:string" />
                                        <xs:element minOccurs="0" name="last-name" type="xs:string" />
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="price" type="xs:decimal" />
                        </xs:sequence>
                        <xs:attribute name="genre" type="xs:string" use="required" />
                        <xs:attribute name="publicationdate" type="xs:date" use="required" />
                        <xs:attribute name="ISBN" type="xs:string" use="required" />
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

Die Auswirkungen der Stark typierten XML-Datenbearbeitung

Die Klasse verwendet das W3C-XML-Schema als Grundlage für die Beschreibung stark typierter XML.The XPathNavigator class uses the W3C XML Schema as a basis for describing strongly typed XML. Elemente und Attribute können durch Überprüfung anhand eines W3C-XML-Schemadokuments mit Typinformationen versehen werden. Elemente, die andere Elemente oder Attribute enthalten können, werden als komplexe Typen bezeichnet, während solche, die nur Textinhalte enthalten können, einfache Typen genannt werden.

Hinweis

Attribute können nur einfache Typen haben.

Ein Element oder Attribut kann als schema valid betrachtet werden, wenn es allen Regeln entspricht, die für die Typdefinition spezifisch sind. Ein Element mit dem einfachen Typ xs:int muss einen numerischen Wert zwischen -2147483648 und 2147483647 enthalten, um schema valid zu sein. Bei komplexen Typen hängt die Schemagültigkeit des Elements von der Schemagültigkeit der untergeordneten Elemente und Attribute ab. Wenn also ein Element anhand seiner komplexen Typdefinition gültig ist, sind alle untergeordneten Elemente und Attribute für ihre Typdefinitionen gültig. Ebenso, wenn sogar eines der untergeordneten Elemente oder Attribute eines Elements aufgrund seiner Typdefinition ungültig ist oder eine unbekannte Gültigkeit hat, ist das Element ebenfalls ungültig oder hat eine unbekannte Gültigkeit.

Da die Gültigkeit eines Elements von der Gültigkeit seiner untergeordneten Elemente und Attribute abhängig ist, führen Änderungen zu einer Änderung der Gültigkeit des Elements, wenn es zuvor gültig war. Wenn die untergeordneten Elemente oder Attribute eines Elements eingefügt, aktualisiert oder gelöscht werden, wird die Gültigkeit des Elements unbekannt. Dies wird durch die Validity-Eigenschaft der SchemaInfo-Eigenschaft des Elements dargestellt, die auf NotKnown festgelegt wird. Darüber hinaus pflanzt sich dieser Effekt rekursiv nach oben über das XML-Dokument fort, da die Gültigkeit des übergeordneten Elements (und des übergeordneten Elements davon, und so weiter) ebenfalls unbekannt wird.

Weitere Informationen zur Schemaüberprüfung und zur XPathNavigator Klasse finden Sie unter Schemaüberprüfung mit XPathNavigator.

Ändern von Attributen

Die Methoden SetValue und SetTypedValue können verwendet werden, um nicht typisierte und typisierte Attributknoten sowie die anderen Knotentypen zu ändern, die im Abschnitt "Knoten ändern" aufgeführt sind.

Im folgenden Beispiel wird der Wert des Attributs genre des ersten book Elements in der books.xml Datei geändert.

Dim document As XmlDocument = New XmlDocument()
document.Load("books.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()

navigator.MoveToChild("bookstore", String.Empty)
navigator.MoveToChild("book", String.Empty)
navigator.MoveToAttribute("genre", String.Empty)

navigator.SetValue("non-fiction")

navigator.MoveToRoot()
Console.WriteLine(navigator.OuterXml)
XmlDocument document = new XmlDocument();
document.Load("books.xml");
XPathNavigator navigator = document.CreateNavigator();

navigator.MoveToChild("bookstore", String.Empty);
navigator.MoveToChild("book", String.Empty);
navigator.MoveToAttribute("genre", String.Empty);

navigator.SetValue("non-fiction");

navigator.MoveToRoot();
Console.WriteLine(navigator.OuterXml);

Weitere Informationen zu den SetValue Und-Methoden SetTypedValue finden Sie in den Abschnitten "Ändern untypierter Werte" und "Ändern von typisierten Werten".

InnerXml- und OuterXml-Eigenschaften

Die Eigenschaften InnerXml und OuterXml der Klasse XPathNavigator ändern das XML-Markup der Knoten, auf denen ein XPathNavigator Objekt derzeit positioniert ist.

Die InnerXml Eigenschaft ändert das XML-Markup der untergeordneten Knoten, an dem ein XPathNavigator Objekt derzeit mit dem analysierten Inhalt des angegebenen XML stringpositioniert ist. Ebenso ändert die OuterXml Eigenschaft das XML-Markup der untergeordneten Knoten, auf denen ein XPathNavigator Objekt derzeit positioniert ist, sowie den aktuellen Knoten selbst.

Im folgenden Beispiel wird die OuterXml Eigenschaft verwendet, um den Wert des price Elements zu ändern und ein neues discount Attribut für das erste book Element in der contosoBooks.xml Datei einzufügen.

Dim document As XmlDocument = New XmlDocument()
document.Load("contosoBooks.xml");
Dim navigator As XPathNavigator = document.CreateNavigator()

navigator.MoveToChild("bookstore", "http://www.contoso.com/books")
navigator.MoveToChild("book", "http://www.contoso.com/books")
navigator.MoveToChild("price", "http://www.contoso.com/books")

navigator.OuterXml = "<price discount=\"0\">10.99</price>"

navigator.MoveToRoot()
Console.WriteLine(navigator.OuterXml)
XmlDocument document = new XmlDocument();
document.Load("contosoBooks.xml");
XPathNavigator navigator = document.CreateNavigator();

navigator.MoveToChild("bookstore", "http://www.contoso.com/books");
navigator.MoveToChild("book", "http://www.contoso.com/books");
navigator.MoveToChild("price", "http://www.contoso.com/books");

navigator.OuterXml = "<price discount=\"0\">10.99</price>";

navigator.MoveToRoot();
Console.WriteLine(navigator.OuterXml);

Im Beispiel wird die contosoBooks.xml Datei als Eingabe verwendet.

<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
    <book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
        <title>The Autobiography of Benjamin Franklin</title>
        <author>
            <first-name>Benjamin</first-name>
            <last-name>Franklin</last-name>
        </author>
        <price>8.99</price>
    </book>
    <book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
        <title>The Confidence Man</title>
        <author>
            <first-name>Herman</first-name>
            <last-name>Melville</last-name>
        </author>
        <price>11.99</price>
    </book>
    <book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
        <title>The Gorgias</title>
        <author>
            <name>Plato</name>
        </author>
        <price>9.99</price>
    </book>
</bookstore>

Ändern von Namespaceknoten

Im Dom (Document Object Model) werden Namespacedeklarationen behandelt, als ob es sich um reguläre Attribute handelt, die eingefügt, aktualisiert und gelöscht werden können. Die XPathNavigator Klasse lässt solche Vorgänge auf Namespaceknoten nicht zu, da das Ändern des Werts eines Namespaceknotens die Identität der Elemente und Attribute im Bereich des Namespaceknotens ändern kann, wie im folgenden Beispiel dargestellt.

<root xmlns="http://www.contoso.com">
    <child />
</root>

Wenn das obige XML-Beispiel folgendermaßen geändert wird, wird dadurch jedes Element im Dokument effektiv umbenannt, da der Wert des Namespace-URI jedes Elements geändert wird.

<root xmlns="urn:contoso.com">
    <child />
</root>

Das Einfügen von Namespaceknoten, die keinen Konflikt mit Namespacedeklarationen im Bereich haben, in den sie eingefügt werden, ist von der XPathNavigator Klasse zulässig. In diesem Fall werden die Namespacedeklarationen nicht in niedrigeren Bereichen im XML-Dokument deklariert und führen nicht zu einer Umbenennung wie im folgenden Beispiel veranschaulicht.

<root xmlns:a="http://www.contoso.com">
    <parent>
        <a:child />
    </parent>
</root>

Wenn das obige XML-Beispiel folgendermaßen geändert wird, werden die Namespacedeklarationen ordnungsgemäß über das XML-Dokument unter dem Bereich der anderen Namespacedeklaration verteilt.

<root xmlns:a="http://www.contoso.com">
    <parent a:parent-id="1234" xmlns:a="http://www.contoso.com/parent-id">
        <a:child xmlns:a="http://www.contoso.com/" />
    </parent>
</root>

Im obigen XML-Beispiel wird das Attribut a:parent-id für das parent Element im http://www.contoso.com/parent-id Namespace eingefügt. Die CreateAttribute Methode wird verwendet, um das Attribut einzufügen, während es parent im Element positioniert ist. Die http://www.contoso.com Namespacedeklaration wird automatisch von der XPathNavigator Klasse eingefügt, um die Konsistenz des restlichen XML-Dokuments beizubehalten.

Ändern von Entitätsverweisknoten

Entitätsverweisknoten in einem XmlDocument Objekt sind schreibgeschützt und können nicht mit den XPathNavigator Klassen oder XmlNode Klassen bearbeitet werden. Jeder Versuch, einen Entitätsverweisknoten zu ändern, führt zu einem InvalidOperationException.

Ändern von xsi:nil-Knoten

Die W3C-XML-Schemaempfehlung führt das Konzept eines Elements ein, das nillierbar ist. Wenn ein Element nillierbar ist, ist es möglich, dass das Element keinen Inhalt hat und trotzdem gültig ist. Das Konzept eines Elements, das nillierbar ist, ähnelt dem Konzept eines Objekts null. Der Hauptunterschied besteht darin, dass auf ein null Objekt nicht auf irgendeine Weise zugegriffen werden kann, während ein xsi:nil Element weiterhin Eigenschaften wie Attribute aufweist, auf die zugegriffen werden kann, aber keinen Inhalt hat (untergeordnete Elemente oder Text). Das Vorhandensein des xsi:nil Attributs mit dem Wert true in einem Element eines XML-Dokuments wird verwendet, um anzugeben, dass ein Element keinen Inhalt aufweist.

Wenn ein XPathNavigator Objekt zum Hinzufügen von Inhalt zu einem gültigen Element mit einem xsi:nil Attribut mit einem Wert von true verwendet wird, wird der Wert des xsi:nil Attributs auf false festgelegt.

Hinweis

Wenn der Inhalt eines Elements mit einem xsi:nil Attribut auf false gesetzt gelöscht wird, wird der Wert des Attributs nicht zu true geändert.

Speichern eines XML-Dokuments

Das Speichern von Änderungen, die an einem XmlDocument Objekt vorgenommen wurden, als Ergebnis der in diesem Thema beschriebenen Bearbeitungsmethoden wird mithilfe der Methoden der XmlDocument Klasse ausgeführt. Weitere Informationen zum Speichern von An einem XmlDocument Objekt vorgenommenen Änderungen finden Sie unter Speichern und Schreiben eines Dokuments.

Siehe auch