Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
La XPathNavigator clase proporciona un conjunto de métodos usados para modificar nodos y valores en un documento XML. Para poder usar estos métodos, el XPathNavigator objeto debe ser editable, es decir, su CanEdit propiedad debe ser true
.
XPathNavigator Los objetos que pueden editar un documento XML se crean mediante el CreateNavigator método de la XmlDocument clase . XPathNavigator los objetos creados por la XPathDocument clase son de solo lectura y cualquier intento de usar los métodos de edición de un XPathNavigator objeto creado por un XPathDocument objeto da como resultado un NotSupportedException.
Para obtener más información sobre cómo crear objetos editables XPathNavigator , vea Lectura de datos XML mediante XPathDocument y XmlDocument.
Modificación de nodos
Una técnica sencilla para cambiar el valor de un nodo es usar los SetValue métodos y SetTypedValue de la XPathNavigator clase .
En la tabla siguiente se enumeran los efectos de estos métodos en distintos tipos de nodo.
XPathNodeType | Datos modificados |
---|---|
Root | No está soportado. |
Element | Contenido del elemento. |
Attribute | Valor del atributo . |
Text | Contenido de texto. |
ProcessingInstruction | El contenido, excepto el objetivo. |
Comment | Contenido del comentario. |
Namespace | No admitido. |
La XPathNavigator clase también proporciona un conjunto de métodos que se usan para insertar y quitar nodos. Para obtener más información sobre cómo insertar y quitar nodos de un documento XML, vea los temas Insertar datos XML mediante XPathNavigator y Quitar datos XML mediante XPathNavigator .
Modificar valores no tipados
El método SetValue simplemente inserta el valor string
sin tipo pasado como parámetro como el valor del nodo donde el objeto XPathNavigator está actualmente ubicado. El valor se inserta sin ningún tipo o sin comprobar que el nuevo valor es válido según el tipo del nodo si la información del esquema está disponible.
En el ejemplo siguiente, el SetValue método se usa para actualizar todos los price
elementos del contosoBooks.xml
archivo.
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)
En el ejemplo se toma el contosoBooks.xml
archivo como entrada.
<?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>
Modificación de valores tipados
Cuando el tipo de un nodo es un tipo simple de esquema XML W3C, el nuevo valor insertado por el SetTypedValue método se comprueba con las facetas del tipo simple antes de establecer el valor. Si el nuevo valor no es válido según el tipo del nodo (por ejemplo, si se establece un valor de -1
en un elemento cuyo tipo es xs:positiveInteger
), se produce una excepción.
En el siguiente ejemplo se intenta cambiar el valor del elemento price
del primer elemento book
del archivo contosoBooks.xml
a un valor DateTime. Dado que el tipo de esquema XML del price
elemento se define como xs:decimal
en los contosoBooks.xsd
archivos, se produce una excepción.
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);
En el ejemplo se toma el contosoBooks.xml
archivo como entrada.
<?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>
El ejemplo también toma el contosoBooks.xsd
como entrada.
<?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>
Efectos de la edición de datos XML fuertemente tipados
La XPathNavigator clase usa el esquema XML W3C como base para describir XML fuertemente tipado. Los elementos y atributos se pueden anotar con información de tipo basada en la validación en un documento de esquema XML W3C. Los elementos que pueden contener otros elementos o atributos se denominan tipos complejos, mientras que los que solo pueden contener contenido textual se denominan tipos simples.
Nota:
Los atributos solo pueden tener tipos simples.
Un elemento o atributo se puede considerar válido para el esquema si se ajusta a todas las reglas específicas de su definición de tipo. Un elemento que tiene el tipo xs:int
simple debe contener un valor numérico entre -2147483648 y 2147483647 para que sea válido para el esquema. Para los tipos complejos, la validez del esquema del elemento depende de la validez del esquema de sus elementos y atributos secundarios. Por lo tanto, si un elemento es válido en su definición de tipo complejo, todos sus elementos secundarios y atributos son válidos en sus definiciones de tipo. Del mismo modo, si incluso uno de los elementos o atributos secundarios de un elemento no es válido en su definición de tipo o tiene una validez desconocida, el elemento también no es válido o de validez desconocida.
Dado que la validez de un elemento depende de la validez de sus elementos secundarios y atributos, cualquier modificación en estos puede alterar la validez del elemento si anteriormente era válido. En concreto, si los elementos o atributos secundarios de un elemento se insertan, actualizan o eliminan, la validez del elemento se vuelve desconocida. Esto se representa mediante la propiedad Validity de la propiedad SchemaInfo del elemento siendo establecida en NotKnown. Además, este efecto se propaga en cascada hacia arriba de forma recursiva en el documento XML, ya que también se desconoce la validez del elemento padre (y del elemento padre de este, y así sucesivamente).
Para obtener más información sobre la validación de esquemas y la XPathNavigator clase , vea Validación de esquemas mediante XPathNavigator.
Modificar atributos
Los métodos SetValue y SetTypedValue se pueden usar para modificar nodos de atributo sin tipo y con tipo, así como otros tipos de nodos enumerados en la sección "Modificación de nodos".
En el siguiente ejemplo se cambia el valor del atributo genre
del primer elemento book
en el archivo books.xml
.
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);
Para obtener más información sobre los SetValue métodos y SetTypedValue , vea las secciones "Modificar valores sin tipo" y "Modificar valores con tipo".
Propiedades InnerXml y OuterXml
Las propiedades InnerXml y OuterXml de la clase XPathNavigator cambian el marcado XML de los nodos en los que un objeto XPathNavigator está posicionado actualmente.
La InnerXml propiedad cambia el marcado XML de los nodos secundarios en los que está colocado un XPathNavigator objeto con el contenido analizado del XML string
especificado. De forma similar, la OuterXml propiedad cambia el marcado XML de los nodos secundarios en los que se coloca un XPathNavigator objeto, así como en el propio nodo actual.
En el ejemplo siguiente se usa la OuterXml propiedad para modificar el valor del price
elemento e insertar un nuevo discount
atributo en el primer book
elemento del contosoBooks.xml
archivo.
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);
En el ejemplo se toma el contosoBooks.xml
archivo como entrada.
<?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>
Modificar nodos de espacio de nombres
En el Modelo de objetos de documento (DOM), las declaraciones de espacio de nombres se tratan como si fueran atributos normales que se pueden insertar, actualizar y eliminar. La XPathNavigator clase no permite estas operaciones en nodos de espacio de nombres porque modificar el valor de un nodo de espacio de nombres puede cambiar la identidad de los elementos y atributos dentro del ámbito del nodo de espacio de nombres, como se muestra en el ejemplo siguiente.
<root xmlns="http://www.contoso.com">
<child />
</root>
Si el ejemplo XML anterior se cambia de la siguiente manera, esto cambia de forma eficaz todos los elementos del documento porque se cambia el valor del URI del espacio de nombres de cada elemento.
<root xmlns="urn:contoso.com">
<child />
</root>
La clase XPathNavigator permite insertar nodos de espacio de nombres que no entren en conflicto con las declaraciones de espacio de nombres dentro del ámbito en el que se insertan. En este caso, las declaraciones de espacio de nombres no se declaran en ámbitos más bajos del documento XML y no resulta en un cambio de nombre, como se ilustra en el ejemplo siguiente.
<root xmlns:a="http://www.contoso.com">
<parent>
<a:child />
</parent>
</root>
Si se cambia el ejemplo XML anterior de la siguiente manera, las declaraciones de espacio de nombres se propagan correctamente en el documento XML debajo del ámbito de la otra declaración de espacio de nombres.
<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>
En el ejemplo XML anterior, el atributo a:parent-id
se inserta en el elemento parent
del espacio de nombres http://www.contoso.com/parent-id
. El CreateAttribute método se usa para insertar el atributo mientras se coloca en el parent
elemento . La declaración de espacio de nombres http://www.contoso.com
se inserta automáticamente por la clase XPathNavigator para conservar la coherencia del resto del documento XML.
Modificar nodos de referencia de entidad
Los nodos de referencia de entidad de un XmlDocument objeto son de solo lectura y no se pueden editar mediante las XPathNavigator clases o XmlNode . Cualquier intento de modificar un nodo de referencia de entidad da como resultado un InvalidOperationException.
Modificación de nodos xsi:nil
La recomendación del esquema XML del W3C introduce el concepto de un elemento que puede ser nulo. Cuando un elemento es nillable, es posible que el elemento no tenga contenido y siga siendo válido. El concepto de que un elemento sea nillable es similar al concepto de que un objeto sea null
. La principal diferencia es que no se puede tener acceso a un null
objeto de ninguna manera, mientras que un xsi:nil
elemento todavía tiene propiedades como atributos a los que se puede tener acceso, pero no tiene contenido (elementos secundarios o texto). La existencia del xsi:nil
atributo con un valor de true
en un elemento de un documento XML se usa para indicar que un elemento no tiene contenido.
Si se usa un XPathNavigator objeto para agregar contenido a un elemento válido con un xsi:nil
atributo con un valor de true
, el valor de su xsi:nil
atributo se establece en false
.
Nota:
Si se elimina el contenido de un elemento con un xsi:nil
atributo establecido en false
, el valor del atributo no cambia a true
.
Guardar un documento XML
Guardar los cambios realizados en un XmlDocument objeto como resultado de los métodos de edición descritos en este tema se realiza mediante los métodos de la XmlDocument clase . Para obtener más información sobre cómo guardar los cambios realizados en un XmlDocument objeto, vea Guardar y escribir un documento.