Sdílet prostřednictvím


Úprava dat XML pomocí XPathNavigatoru

Třída XPathNavigator poskytuje sadu metod sloužících k úpravě uzlů a hodnot v dokumentu XML. Aby bylo možné tyto metody použít, XPathNavigator musí být objekt upravitelný, to znamená, že jeho CanEdit vlastnost musí být true.

XPathNavigator objekty, které mohou upravovat dokument XML jsou vytvořeny CreateNavigator metodou XmlDocument třídy. XPathNavigator objekty vytvořené třídou XPathDocument jsou určeny pouze pro čtení a jakýkoli pokus o použití editačních metod objektu XPathNavigator vytvořeného objektem XPathDocument má za následek NotSupportedException.

Další informace o vytváření upravitelných XPathNavigator objektů naleznete v tématu Čtení dat XML pomocí XPathDocument a XmlDocument.

Úprava uzlů

Jednoduchou technikou, jak změnit hodnotu uzlu, je použít metody SetValue a SetTypedValue třídy XPathNavigator.

Následující tabulka uvádí účinky těchto metod na různé typy uzlů.

XPathNodeType Změna dat
Root Není podporováno.
Element Obsah elementu.
Attribute Hodnota atributu.
Text Textový obsah.
ProcessingInstruction Obsah kromě cíle.
Comment Obsah komentáře.
Namespace Nepodporuje se.

Poznámka:

Úpravy uzlů Namespace nebo uzlu Root nejsou podporovány.

Třída XPathNavigator také poskytuje sadu metod používaných k vložení a odebrání uzlů. Další informace o vkládání a odebírání uzlů z dokumentu XML naleznete v tématu Vložení DAT XML pomocí XPathNavigator a Odebrání dat XML pomocí XPathNavigator témat.

Úprava netypových hodnot

Metoda SetValue jednoduše vloží nezatypovanou hodnotu předanou string jako parametr jako hodnotu uzlu XPathNavigator , na který je objekt aktuálně umístěn. Hodnota se vloží bez jakéhokoli typu nebo bez ověření, zda je nová hodnota platná podle typu uzlu, pokud jsou k dispozici informace o schématu.

V následujícím příkladu se SetValue metoda používá k aktualizaci všech price prvků v contosoBooks.xml souboru.

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)

Příklad vezme contosoBooks.xml soubor jako vstup.

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

Úprava zadaných hodnot

Pokud je typ uzlu jednoduchý typ schématu W3C XML, nová hodnota vložená metodou SetTypedValue je kontrolována proti omezujícím vlastnostem jednoduchého typu před nastavením hodnoty. Pokud nová hodnota není platná podle typu uzlu (například nastavení hodnoty -1 prvku, jehož typ je xs:positiveInteger), výsledkem je výjimka.

Následující příklad se pokusí změnit hodnotu price prvku prvního book prvku v contosoBooks.xml souboru na DateTime hodnotu. Vzhledem k tomu, že typ schématu XML elementu price je definován jako xs:decimal v contosoBooks.xsd souborech, výsledkem je výjimka.

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

Příklad vezme contosoBooks.xml soubor jako vstup.

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

Příklad také přebírá contosoBooks.xsd jako vstup.

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

Účinky úprav silně typovaných dat XML

Třída XPathNavigator používá schéma XML W3C jako základ pro popis xml silného typu. Elementy a atributy lze anotovat informacemi o typu na základě ověření v dokumentu schématu XML W3C. Prvky, které mohou obsahovat jiné prvky nebo atributy, se nazývají komplexní typy, zatímco ty, které mohou obsahovat pouze textový obsah, se nazývají jednoduché typy.

Poznámka:

Atributy můžou mít pouze jednoduché typy.

Prvek nebo atribut lze považovat za platný schématu, pokud odpovídá všem pravidlům specifickým pro definici typu. Prvek, který má jednoduchý typ xs:int , musí obsahovat číselnou hodnotu mezi -2147483648 a 2147483647, aby byla platná schématu. U složitých typů je platnost schématu prvku závislá na platnosti schématu jeho podřízených elementů a atributů. Proto pokud je prvek platný pro definici komplexního typu, všechny jeho podřízené prvky a atributy jsou platné pro jejich definice typu. Podobně platí, že pokud je i jeden z podřízených prvků nebo atributů elementu neplatný vůči definici jeho typu nebo má neznámou platnost, je prvek také neplatný nebo neznámý platnost.

Vzhledem k tomu, že platnost prvku závisí na platnosti jeho podřízených prvků a atributů, jakékoli změny v nich povedou ke změně platnosti prvku, pokud byl předtím platný. Konkrétně, pokud podřízené prvky nebo atributy elementu jsou vloženy, aktualizovány nebo odstraněny, pak platnost prvku bude neznámá. Tato vlastnost je reprezentována Validity vlastností prvku SchemaInfo , která je nastavena na NotKnown. Kromě toho se tento efekt rekurzivně šíří nahoru v celém dokumentu XML, protože platnost nadřazeného elementu daného elementu (a jeho nadřazeného elementu atd.) je také neznámá.

Další informace o ověřování schématu XPathNavigator a třídě naleznete v tématu Ověření schématu pomocí XPathNavigator.

Úprava atributů

Tyto metody SetValue a SetTypedValue lze použít k úpravě netypovaných a typovaných uzlů atributů a dalších typů uzlů uvedených v části "Úpravy uzlů".

Následující příklad změní hodnotu genre atributu prvního book prvku v books.xml souboru.

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

Další informace o metodách SetValue a SetTypedValue o úpravách hodnot naleznete v částech "Úpravy nezatypovaných hodnot" a "Úpravy typových hodnot".

InnerXml a OuterXml – vlastnosti

Vlastnosti InnerXml a OuterXml třídy XPathNavigator mění XML kód uzlů, na kterých je objekt XPathNavigator aktuálně umístěn.

Vlastnost InnerXml změní kód XML u podřízených uzlů, na nichž je objekt XPathNavigator aktuálně umístěn, pomocí parsovaného obsahu zadaného XML string. Podobně vlastnost OuterXml změní značky XML podřízených uzlů XPathNavigator, na které je objekt aktuálně umístěn, stejně jako samotný aktuální uzel.

Následující příklad používá OuterXml vlastnost k úpravě hodnoty price elementu a vložení nového discount atributu na první book prvek v contosoBooks.xml souboru.

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

Příklad vezme contosoBooks.xml soubor jako vstup.

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

Úprava uzlů oboru názvů

V modelu DOM (Document Object Model) se deklarace oboru názvů považují za běžné atributy, které lze vložit, aktualizovat a odstranit. XPathNavigator Třída neumožňuje takové operace na uzlech oboru názvů, protože změna hodnoty uzlu oboru názvů může změnit identitu prvků a atributů v oboru názvů uzlu, jak je znázorněno v následujícím příkladu.

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

Pokud se výše uvedený příklad XML změní následujícím způsobem, tento postup efektivně přejmenuje každý prvek v dokumentu, protože hodnota identifikátoru URI oboru názvů každého prvku je změněna.

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

Vkládání uzlů oboru názvů, které nejsou v konfliktu s deklaracemi oboru názvů v místě, kam jsou vloženy, je povoleno třídou XPathNavigator. V tomto případě deklarace oboru názvů nejsou uvedeny v nižších úrovních dokumentu XML a nevedou k přejmenování, jak je znázorněno v následujícím příkladu.

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

Pokud se výše uvedený příklad XML změní následujícím způsobem, deklarace oboru názvů se správně rozšíří v rámci dokumentu XML pod rozsahem ostatních deklarací oboru názvů.

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

V příkladu XML výše je atribut a:parent-id vložen na elementu parent v rámci oboru názvů http://www.contoso.com/parent-id. Metoda CreateAttribute se používá k vložení atributu při umístění na elementu parent . Deklarace http://www.contoso.com oboru názvů se automaticky vloží XPathNavigator třídou, aby se zachovala konzistence zbytku dokumentu XML.

Úprava referenčních uzlů entity

Referenční uzly entit v objektu XmlDocument jsou jen pro čtení a nelze je upravovat pomocí těchto XPathNavigator tříd.XmlNode Výsledkem jakéhokoli pokusu o úpravu referenčního uzlu entity je .InvalidOperationException

Úprava uzlů xsi:nil

Doporučení schématu W3C XML představuje koncept prvku, který je neschválitelný. Pokud je prvek nulovatelný, je možné, aby neměl žádný obsah a přesto byl platný. Koncept prvku, který může být nulový, je podobný konceptu objektu je null. Hlavní rozdíl spočívá v tom, že k objektu null nelze přistupovat žádným způsobem, zatímco xsi:nil prvek má vlastnosti, jako jsou atributy, ke kterým lze získat přístup, ale nemá žádný obsah (podřízené prvky nebo text). Existence atributu xsi:nil s hodnotou true prvku v dokumentu XML se používá k označení, že prvek nemá žádný obsah.

Pokud se XPathNavigator objekt používá k přidání obsahu do platného xsi:nil prvku s atributem s hodnotou true, hodnota jeho xsi:nil atributu je nastavena na false.

Poznámka:

Pokud je obsah prvku s atributem xsi:nil nastaveným na false odstraněn, hodnota atributu se nezmění na true.

Uložení dokumentu XML

Uložení změn provedených v objektu XmlDocument v důsledku metod úprav popsaných v tomto tématu se provádí pomocí metod XmlDocument třídy. Další informace o ukládání změn provedených v objektu XmlDocument naleznete v tématu Ukládání a zápis dokumentu.

Viz také