Delen via


XML-gegevens wijzigen met XPathNavigator

De XPathNavigator klasse biedt een set methoden die worden gebruikt om knooppunten en waarden in een XML-document te wijzigen. Als u deze methoden wilt gebruiken, moet het XPathNavigator object kunnen worden bewerkt, dat wil gezegd: CanEdit de eigenschap ervan moet zijn true.

XPathNavigator objecten die een XML-document kunnen bewerken, worden gemaakt door de CreateNavigator methode van de XmlDocument klasse. XPathNavigator objecten die door de XPathDocument klasse zijn gemaakt, zijn alleen-lezen en pogingen om de bewerkingsmethoden te gebruiken van een XPathNavigator object dat door een XPathDocument object is gemaakt, resulteert in een NotSupportedException.

Zie XML-gegevens lezen met XPathDocument en XmlDocument voor meer informatie over het maken van bewerkbare XPathNavigator objecten.

Knooppunten wijzigen

Een eenvoudige techniek voor het wijzigen van de waarde van een knooppunt is het gebruik van de SetValue en SetTypedValue methoden van de XPathNavigator klasse.

De volgende tabel bevat de effecten van deze methoden op verschillende knooppunttypen.

XPathNodeType Gegevens gewijzigd
Root Wordt niet ondersteund.
Element De inhoud van het element.
Attribute De waarde van het kenmerk.
Text De tekstinhoud.
ProcessingInstruction De inhoud, met uitzondering van het doel.
Comment De inhoud van de opmerking.
Namespace Niet ondersteund.

Notitie

Het bewerken van Namespace knooppunten of het Root knooppunt wordt niet ondersteund.

De XPathNavigator klasse biedt ook een set methoden die worden gebruikt om knooppunten in te voegen en te verwijderen. Zie de onderwerpen XML-gegevens invoegen met XPathNavigator en XML-gegevens verwijderen met behulp van XPathNavigator en XPathNavigator voor meer informatie over het invoegen en verwijderen van knooppunten uit een XML-document.

Niet-getypte waarden wijzigen

Met SetValue de methode wordt de niet-getypte string waarde ingevoegd die als parameter wordt doorgegeven als de waarde van het knooppunt waarop het XPathNavigator object momenteel is geplaatst. De waarde wordt ingevoegd zonder enig type of zonder te controleren of de nieuwe waarde geldig is volgens het type van het knooppunt als er schemagegevens beschikbaar zijn.

In het volgende voorbeeld wordt de SetValue methode gebruikt om alle price elementen in het contosoBooks.xml bestand bij te werken.

XmlDocument^ document = gcnew XmlDocument();
document->Load("contosoBooks.xml");
XPathNavigator^ navigator = document->CreateNavigator();

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

for each (XPathNavigator^ nav in navigator->Select("//bk:price", manager))
{
    if(nav->Value == "11.99")
    {
        nav->SetValue("12.99");
    }
}

Console::WriteLine(navigator->OuterXml);
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)

In het voorbeeld wordt het contosoBooks.xml bestand als invoer gebruikt.

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

Getypte waarden wijzigen

Wanneer het type van een knooppunt een eenvoudig type W3C XML-schema is, wordt de nieuwe waarde die door de SetTypedValue methode is ingevoegd, gecontroleerd op de facetten van het eenvoudige type voordat de waarde wordt ingesteld. Als de nieuwe waarde niet geldig is op basis van het type van het knooppunt (bijvoorbeeld het instellen van een waarde van -1 een element waarvan het type is xs:positiveInteger), resulteert deze in een uitzondering.

In het volgende voorbeeld wordt geprobeerd de waarde van het element van het price eerste book element in het contosoBooks.xml bestand te wijzigen in een DateTime waarde. Omdat het XML-schematype van het price element is gedefinieerd als xs:decimal in de contosoBooks.xsd bestanden, resulteert dit in een uitzondering.

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

In het voorbeeld wordt het contosoBooks.xml bestand als invoer gebruikt.

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

In het voorbeeld wordt ook de contosoBooks.xsd invoer gebruikt.

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

De effecten van het bewerken van sterk getypte XML-gegevens

De XPathNavigator klasse maakt gebruik van het W3C XML-schema als basis voor het beschrijven van sterk getypte XML. Elementen en kenmerken kunnen worden geannoteerd met typegegevens op basis van validatie voor een W3C XML-schemadocument. Elementen die andere elementen of kenmerken kunnen bevatten, worden complexe typen genoemd, terwijl elementen die alleen tekstuele inhoud kunnen bevatten, eenvoudige typen worden genoemd.

Notitie

Kenmerken kunnen alleen eenvoudige typen hebben.

Een element of kenmerk kan als schema-geldig worden beschouwd als deze voldoet aan alle regels die specifiek zijn voor de typedefinitie. Een element met het eenvoudige type xs:int moet een numerieke waarde bevatten tussen -2147483648 en 2147483647 om schema geldig te zijn. Voor complexe typen is de schema-geldigheid van het element afhankelijk van de schema-geldigheid van de onderliggende elementen en kenmerken. Dus als een element geldig is op basis van de complexe typedefinitie, zijn alle onderliggende elementen en kenmerken geldig voor hun typedefinities. Als zelfs een van de onderliggende elementen of kenmerken van een element ongeldig is ten opzichte van de typedefinitie of een onbekende geldigheid heeft, is het element ook ongeldig of van onbekende geldigheid.

Aangezien de geldigheid van een element afhankelijk is van de geldigheid van de onderliggende elementen en kenmerken, resulteren wijzigingen in beide elementen in een wijziging van de geldigheid van het element als het eerder geldig was. Als de onderliggende elementen of kenmerken van een element worden ingevoegd, bijgewerkt of verwijderd, wordt de geldigheid van het element onbekend. Dit wordt vertegenwoordigd door de Validity eigenschap van de eigenschap van het element SchemaInfo dat wordt ingesteld op NotKnown. Bovendien wordt dit effect recursief omhoog in het XML-document, omdat de geldigheid van het bovenliggende element (en het bovenliggende element, enzovoort) ook onbekend wordt.

Zie Schemavalidatie met behulp van XPathNavigator voor meer informatie over schemavalidatie en de XPathNavigator klasse.

Kenmerken wijzigen

De SetValue en SetTypedValue methoden kunnen worden gebruikt om niet-getypte en getypte kenmerkknooppunten te wijzigen, evenals de andere knooppunttypen die worden vermeld in de sectie 'Knooppunten wijzigen'.

In het volgende voorbeeld wordt de waarde van het kenmerk van het genre eerste book element in het books.xml bestand gewijzigd.

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

Zie de secties 'Niet-getypte waarden wijzigen' en 'Getypte waarden wijzigen' voor meer informatie over de SetValue en SetTypedValue methoden.

Eigenschappen van InnerXml en OuterXml

De InnerXml eigenschappen van OuterXml de XPathNavigator klasse wijzigen de XML-opmaak van de knooppunten waarop een XPathNavigator object momenteel is geplaatst.

De InnerXml eigenschap wijzigt de XML-opmaak van de onderliggende knooppunten waarop een XPathNavigator object momenteel is geplaatst met de geparseerde inhoud van de opgegeven XML string. Op dezelfde manier wijzigt de OuterXml eigenschap de XML-opmaak van de onderliggende knooppunten waarop een XPathNavigator object momenteel is geplaatst, evenals het huidige knooppunt zelf.

In het volgende voorbeeld wordt de OuterXml eigenschap gebruikt om de waarde van het price element te wijzigen en een nieuw discount kenmerk in te voegen op het eerste book element in het contosoBooks.xml bestand.

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

In het voorbeeld wordt het contosoBooks.xml bestand als invoer gebruikt.

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

Naamruimteknooppunten wijzigen

In het Document Object Model (DOM) worden naamruimtedeclaraties behandeld alsof ze reguliere kenmerken zijn die kunnen worden ingevoegd, bijgewerkt en verwijderd. De XPathNavigator klasse staat dergelijke bewerkingen niet toe op naamruimteknooppunten, omdat het wijzigen van de waarde van een naamruimteknooppunt de identiteit van de elementen en kenmerken binnen het bereik van het naamruimteknooppunt kan wijzigen, zoals wordt geïllustreerd in het volgende voorbeeld.

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

Als het bovenstaande XML-voorbeeld op de volgende manier wordt gewijzigd, wordt de naam van elk element in het document gewijzigd omdat de waarde van de naamruimte-URI van elk element wordt gewijzigd.

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

Het invoegen van naamruimteknooppunten die niet conflicteren met naamruimtedeclaraties in het bereik waarin ze worden ingevoegd, is toegestaan door de XPathNavigator klasse. In dit geval worden de naamruimtedeclaraties niet gedeclareerd bij lagere bereiken in het XML-document en resulteert dit niet in een andere naam, zoals geïllustreerd in het volgende voorbeeld.

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

Als het bovenstaande XML-voorbeeld op de volgende manier wordt gewijzigd, worden de naamruimtedeclaraties correct doorgegeven in het XML-document onder het bereik van de andere naamruimtedeclaratie.

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

In het bovenstaande XML-voorbeeld wordt het kenmerk a:parent-id ingevoegd op het parent element in de http://www.contoso.com/parent-id naamruimte. De CreateAttribute methode wordt gebruikt om het kenmerk in te voegen terwijl het op het parent element is geplaatst. De http://www.contoso.com naamruimtedeclaratie wordt automatisch door de XPathNavigator klasse ingevoegd om de consistentie van de rest van het XML-document te behouden.

Entiteitsverwijzingsknooppunten wijzigen

Entiteitsverwijzingsknooppunten in een XmlDocument object hebben het kenmerk Alleen-lezen en kunnen niet worden bewerkt met behulp van de XPathNavigator of XmlNode klassen. Elke poging om een entiteitsreferentieknooppunt te wijzigen, resulteert in een InvalidOperationException.

XSI:nil-knooppunten wijzigen

De aanbeveling voor het W3C XML-schema introduceert het concept van een element dat niet kan worden gebruikt. Wanneer een element niet kan worden gebruikt, is het mogelijk dat het element geen inhoud heeft en nog steeds geldig is. Het concept van een element dat nillable is, is vergelijkbaar met het concept van een object.null Het belangrijkste verschil is dat een null object op geen enkele manier kan worden geopend, terwijl een xsi:nil element nog steeds eigenschappen heeft, zoals kenmerken die kunnen worden geopend, maar geen inhoud heeft (onderliggende elementen of tekst). Het bestaan van het xsi:nil kenmerk met een waarde van true een element in een XML-document wordt gebruikt om aan te geven dat een element geen inhoud heeft.

Als een XPathNavigator object wordt gebruikt om inhoud toe te voegen aan een geldig element met een xsi:nil kenmerk met een waarde van true, wordt de waarde van xsi:nil het kenmerk ingesteld op false.

Notitie

Als de inhoud van een element waarop een xsi:nil kenmerk is ingesteld false , wordt verwijderd, wordt de waarde van het kenmerk niet gewijzigd in true.

Een XML-document opslaan

Het opslaan van wijzigingen in een XmlDocument object als gevolg van de bewerkingsmethoden die in dit onderwerp worden beschreven, wordt uitgevoerd met behulp van de methoden van de XmlDocument klasse. Zie Een document opslaan en schrijven voor meer informatie over het opslaan van wijzigingen in een XmlDocument object.

Zie ook