XML-adatok módosítása az XPathNavigator használatával

Az XPathNavigator osztály az XML-dokumentumok csomópontjainak és értékeinek módosítására szolgáló módszerek készletét biztosítja. A metódusok használatához az XPathNavigator objektumnak szerkeszthetőnek kell lennie, azaz a tulajdonságának CanEdit kell lennie true.

XPathNavigator az XML-dokumentumokat szerkeszteni képes objektumok az CreateNavigator osztály metódusával XmlDocument jönnek létre. XPathNavigatorA XPathDocument osztály által létrehozott objektumok írásvédettek, és bármilyen kísérlet, amely egy XPathNavigator objektum által létrehozott XPathDocument objektum szerkesztési módszereit használja, eredménye egy NotSupportedException.

A szerkeszthető XPathNavigator objektumok létrehozásáról további információt az XML-adatok olvasása az XPathDocument és az XmlDocument használatával című témakörben talál.

Csomópontok módosítása

A csomópont értékének módosítására szolgáló egyszerű technika a SetValue és SetTypedValue metódusok használata a XPathNavigator osztályban.

Az alábbi táblázat felsorolja ezeknek a módszereknek a különböző csomóponttípusokra gyakorolt hatásait.

XPathNodeType Adatok megváltoztak
Root Nem támogatott.
Element Az elem tartalma.
Attribute Az attribútum értéke.
Text A szöveges tartalom.
ProcessingInstruction A tartalom, a cél kivételével.
Comment A megjegyzés tartalma.
Namespace Nem támogatott.

Megjegyzés:

Az Namespace csomópontok vagy a Root csomópont szerkesztése nem támogatott.

Az XPathNavigator osztály emellett a csomópontok beszúrására és eltávolítására szolgáló módszerek készletét is biztosítja. A csomópontok XML-dokumentumból való beszúrásával és eltávolításával kapcsolatos további információkért tekintse meg az XML-adatok beszúrása XPathNavigator használatával és az XML-adatok eltávolítása XPathNavigator-témakörökkel című témakört.

Nem beírt értékek módosítása

A SetValue metódus egyszerűen beszúrja a paraméterként átadott nem beírt string értéket annak a csomópontnak XPathNavigator az értékeként, amelyen az objektum jelenleg elhelyezve van. Az érték típus nélkül vagy anélkül lesz beszúrva, hogy az új érték érvényes-e a csomópont típusának megfelelően, ha rendelkezésre állnak sémainformációk.

Az alábbi példában a SetValue metódust a price fájlban található összes contosoBooks.xml elem frissítésére használjuk.

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)

A példa bemenetként használja a contosoBooks.xml fájlt.

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

Tipizált értékek módosítása

Ha a csomópont típusa egyszerű W3C XML-sématípus, a metódus által SetTypedValue beszúrt új értéket az érték beállítása előtt a rendszer ellenőrzi az egyszerű típus aspektusai között. Ha az új érték nem érvényes a csomópont típusának megfelelően (például egy elem -1 értékének beállítása, amelynek típusa xs:positiveInteger), az kivételt eredményez.

Az alábbi példa megkísérli a fájl első price elemének book értékét contosoBooks.xml értékre DateTime módosítani. Mivel a price elem XML-sématípusa xs:decimal fájlokban contosoBooks.xsd-ként van definiálva, ez kivételt eredményez.

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

A példa bemenetként használja a contosoBooks.xml fájlt.

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

A példa a contosoBooks.xsd is bemenetként használja.

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

Az erősen beírt XML-adatok szerkesztésének hatásai

Az XPathNavigator osztály a W3C XML-sémát használja az erősen beírt XML leírásának alapjául. Az elemek és attribútumok a W3C XML-sémadokumentumon alapuló ellenőrzésen alapuló típusinformációkkal fűzhetők hozzá. Az egyéb elemeket vagy attribútumokat tartalmazó elemeket összetett típusoknak nevezzük, míg azokat, amelyek csak szöveges tartalmat tartalmazhatnak, egyszerű típusoknak nevezzük.

Megjegyzés:

Az attribútumok csak egyszerű típusok lehetnek.

Az elemek vagy attribútumok séma-érvényesnek tekinthetők, ha megfelelnek a típusdefinícióra vonatkozó összes szabálynak. Az egyszerű típussal xs:int rendelkező elemeknek számértéket kell tartalmazniuk -2147483648 és 2147483647 között, hogy séma-érvényesek legyenek. Összetett típusok esetén az elem séma-érvényessége a gyermekelemek és attribútumok séma-érvényességétől függ. Így ha egy elem érvényes az összetett típusdefiníciójával szemben, az összes gyermekeleme és attribútuma érvényes a típusdefiníciókra. Hasonlóképpen, ha egy elem gyermekelemeinek vagy attribútumainak egyike is érvénytelen a típusdefiníciójával szemben, vagy ismeretlen érvényességgel rendelkezik, akkor az elem is érvénytelen vagy ismeretlen érvényességű.

Mivel egy elem érvényessége a gyermekelemek és attribútumok érvényességétől függ, az elem bármelyikének módosítása az elem érvényességét módosítja, ha korábban érvényes volt. Pontosabban, ha egy elem gyermekelemeit vagy attribútumait beszúrják, frissítik vagy törlik, akkor az elem érvényessége ismeretlen lesz. Ezt az Validity elem SchemaInfo tulajdonsága jelöli, amely a következőre NotKnownvan állítva: . Emellett ez a hatás rekurzívan felfelé halad az XML-dokumentumban, mivel az elem szülőelemének (és annak szülőelemének, és így tovább) érvényessége is ismeretlenné válik.

A sémaérvényesítésről és az osztályról további információt az XPathNavigatorXPathNavigator használatával végzett sémaérvényesítés című témakörben talál.

Attribútumok módosítása

SetValue A SetTypedValue metódusokkal módosíthatja a nem gépelt és beírt attribútumcsomópontokat, valamint a "Csomópontok módosítása" szakaszban felsorolt egyéb csomóponttípusokat.

Az alábbi példa módosítja a genre fájl első book elemének books.xml attribútumának értékét.

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

A SetValue és SetTypedValue metódusokkal kapcsolatos további információkért tekintse meg a "Nem beírt értékek módosítása" és a "Gépelt értékek módosítása" szakaszt.

InnerXml és OuterXml tulajdonságai

A(z) InnerXml osztály OuterXml és XPathNavigator tulajdonságai módosítják azon csomópontok XML jelölését, ahol a XPathNavigator objektum jelenleg elhelyezkedik.

A InnerXml tulajdonság az XPathNavigator objektum által jelenleg pozicionált gyermekcsomópontok XML-jelölését módosítja az adott XML string elemezett tartalma alapján. Hasonlóképpen, a OuterXml tulajdonság megváltoztatja a gyermekcsomópontok XML-jelölését, amelyen XPathNavigator az objektum jelenleg elhelyezve van, valamint az aktuális csomópontot is.

Az alábbi példa az OuterXml elem értékének price módosítására és új discount attribútum beszúrására használja a tulajdonságot a book fájl első contosoBooks.xml elemére.

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

A példa bemenetként használja a contosoBooks.xml fájlt.

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

Névtércsomópontok módosítása

A dokumentumobjektum-modellben (DOM) a névtér-deklarációk úgy lesznek kezelve, mintha normál attribútumok lennének, amelyek beilleszthetők, frissíthetők és törölhetők. Az XPathNavigator osztály nem engedélyezi az ilyen műveleteket a névtércsomópontokon, mert a névtércsomópont értékének módosítása megváltoztathatja a névtércsomópont hatókörén belüli elemek és attribútumok identitását, ahogyan az az alábbi példában látható.

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

Ha a fenti XML-példa a következő módon módosul, ez gyakorlatilag átnevezi a dokumentum minden elemét, mert az egyes elemek névterének URI-értéke módosul.

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

Az XPathNavigator osztály lehetővé teszi olyan névtércsomópontok beszúrását, amelyek nem ütköznek a hatókör névtér-deklarációival, ahová beillesztésre kerülnek. Ebben az esetben a névtér-deklarációk nem deklarálódnak az XML-dokumentumban alacsonyabb hatókörökben, és nem eredményeznek átnevezést az alábbi példában látható módon.

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

Ha a fenti XML-példa a következő módon módosul, a névtér-deklarációk megfelelően propagálódnak az XML-dokumentumban a másik névtér-deklaráció hatóköre alatt.

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

A fenti XML-példában az attribútum a:parent-id a névtér elemére parenthttp://www.contoso.com/parent-id lesz beszúrva. A CreateAttribute metódus az attribútum beszúrására szolgál, miközben az parent elemen van elhelyezve. A http://www.contoso.com névtér deklarációját az XPathNavigator osztály automatikusan beszúrja, hogy megőrizze az XML-dokumentum többi részének konzisztenciáját.

Entitás referenciacsomópontjainak módosítása

Az XmlDocument objektum entitás-referenciacsomópontjai írásvédettek, és nem szerkeszthetők sem a XPathNavigator, sem a XmlNode osztályokkal. Az entitás-referenciacsomópont módosítására tett bármilyen kísérlet eredménye egy InvalidOperationException.

Xsi:nil csomópontok módosítása

A W3C XML séma ajánlás bevezeti a nillálható elem fogalmát. Ha egy elem tagozható, lehetséges, hogy az elem nem rendelkezik tartalommal, és továbbra is érvényes. A 'nill'-t elfogadó elem fogalma hasonló az objektum nullá tehetőségéhez null. A fő különbség az, hogy egy null objektum semmilyen módon nem érhető el, míg egy xsi:nil elemnek továbbra is vannak olyan tulajdonságai, mint például az attribútumok, amelyek elérhetők, de nem tartalmaznak tartalmat (gyermekelemeket vagy szöveget). Az XML-dokumentum egy elemének xsi:nil értékével rendelkező attribútum megléte true azt jelzi, hogy egy elemnek nincs tartalma.

Ha egy XPathNavigator objektum olyan érvényes elemhez ad hozzá tartalmat, amelynek xsi:nil attribútuma értéke true, az attribútum értéke arra van beállítva xsi:nil: false.

Megjegyzés:

Ha egy attribútumkészlettel xsi:nil rendelkező false elem tartalma törlődik, az attribútum értéke nem változik true.

XML-dokumentum mentése

Az objektumon XmlDocument a jelen témakörben ismertetett szerkesztési módszerek eredményeként végrehajtott módosítások mentése az XmlDocument osztály metódusaival történik. Az objektum módosításainak XmlDocument mentéséről további információt a Dokumentum mentése és írása című témakörben talál.

Lásd még