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