Sdílet prostřednictvím


Změna dat XML pomocí XPathNavigator

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é XPathDocument třídou jsou jen pro čtení a všechny pokusy o použití metod úprav objektu XPathNavigator vytvořeného objektem XPathDocument výsledkem objektu 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 změny hodnoty uzlu je použití SetValue metod třídy.SetTypedValueXPathNavigator

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

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

Poznámka:

Namespace Úpravy uzlů nebo uzel Root není podporován.

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

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 dat XML se silnými typy

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 byl 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 je závislá na platnosti jeho podřízených prvků a atributů, změny, které mají za následek změnu platnosti prvku, pokud byl dříve 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 tento efekt kaskáduje rekurzivně v celém dokumentu XML, protože platnost nadřazeného elementu 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 SetValue metody SetTypedValue lze použít k úpravě netypový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

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

Vlastnost InnerXml změní kód XML podřízených XPathNavigator uzlů objekt je nyní umístěn s parsovaným obsahem daného XML string. OuterXml Podobně vlastnost změní kód XML podřízených XPathNavigator uzlů, na které je objekt aktuálně umístěn, stejně jako aktuální uzel samotný.

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 oboru, do kterého jsou vloženy, je povoleno XPathNavigator třídou. V tomto případě deklarace oboru názvů nejsou deklarovány v nižších oborech v dokumentu XML a nemají za následek 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šíří do dokumentu XML pod oborem druhé deklarace 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 se atribut a:parent-id vloží do parent elementu http://www.contoso.com/parent-id v oboru názvů. 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 neposunutelný, je možné, aby prvek neměl žádný obsah a stále je platný. Koncept prvku, který je neillable, 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é