Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
A XPathNavigator classe fornece um conjunto de métodos usados para modificar nós e valores em um documento XML. Para usar esses métodos, o XPathNavigator objeto deve ser editável, ou seja, sua CanEdit propriedade deve ser true.
XPathNavigator os objetos que podem editar um documento XML são criados pelo CreateNavigator método da XmlDocument classe. XPathNavigator os objetos criados pela classe XPathDocument são somente leitura e qualquer tentativa de usar os métodos de edição de um objeto XPathNavigator criado por um objeto XPathDocument resulta em um NotSupportedException.
Para obter mais informações sobre como criar objetos editáveis XPathNavigator , consulte Ler dados XML usando XPathDocument e XmlDocument.
Modificando nós
Uma técnica simples para alterar o valor de um nó é usar os métodos SetValue e SetTypedValue da classe XPathNavigator.
A tabela a seguir apresenta os efeitos desses métodos em diferentes tipos de elementos.
| XPathNodeType | Dados alterados |
|---|---|
| Root | Não há suporte. |
| Element | O conteúdo do elemento. |
| Attribute | O valor do atributo. |
| Text | O conteúdo do texto. |
| ProcessingInstruction | O conteúdo, excluindo o alvo. |
| Comment | O conteúdo do comentário. |
| Namespace | Sem suporte. |
A XPathNavigator classe também fornece um conjunto de métodos usados para inserir e remover nós. Para obter mais informações sobre como inserir e remover nós de um documento XML, consulte os tópicos Inserir Dados XML usando XPathNavigator e Remover Dados XML usando tópicos XPathNavigator .
Modificando Valores Não Tipados
O método SetValue simplesmente insere o valor não tipado string passado como um parâmetro como valor do nó em que o objeto XPathNavigator está atualmente posicionado. O valor é inserido sem verificação de tipo ou sem verificar se o novo valor é válido de acordo com o tipo do nó, caso as informações do esquema estejam disponíveis.
No exemplo a seguir, o SetValue método é usado para atualizar todos os price elementos no contosoBooks.xml arquivo.
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)
O exemplo usa o contosoBooks.xml arquivo como uma 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>
Modificando valores tipados
Quando o tipo de nó é um tipo simples de Esquema XML W3C, o novo valor inserido pelo método SetTypedValue é verificado em relação às facetas do tipo simples antes que o valor seja atribuído. Se o novo valor não for válido de acordo com o tipo do nó (por exemplo, definir um valor em -1 um elemento cujo tipo é xs:positiveInteger), ele resultará em uma exceção.
O exemplo a seguir tenta alterar o valor do elemento price do primeiro elemento book no arquivo contosoBooks.xml para um valor DateTime. Como o tipo de esquema XML do price elemento é definido como xs:decimal nos contosoBooks.xsd arquivos, isso resulta em uma exceção.
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);
O exemplo usa o contosoBooks.xml arquivo como uma 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>
O exemplo também toma contosoBooks.xsd como parte da 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>
Os efeitos da edição de dados XML fortemente tipados
A XPathNavigator classe usa o Esquema XML W3C como base para descrever XML fortemente tipado. Elementos e atributos podem ser anotados com informações de tipo com base na validação em um documento de esquema XML W3C. Elementos que podem conter outros elementos ou atributos são chamados de tipos complexos, enquanto aqueles que só podem conter conteúdo textual são chamados de tipos simples.
Observação
Os atributos só podem ter tipos simples.
Um elemento ou atributo pode ser considerado válido por esquema se estiver em conformidade com todas as regras específicas à sua definição de tipo. Um elemento que tem o tipo simples xs:int precisa conter um valor numérico entre -2147483648 e 2147483647 para ser válido segundo o esquema. Para tipos complexos, a validade do esquema do elemento depende da validade do esquema de seus elementos e atributos filho. Portanto, se um elemento for válido em relação à sua definição de tipo complexo, todos os seus elementos filho e atributos serão válidos em relação às definições de tipo. Da mesma forma, se mesmo um dos elementos filho ou atributos de um elemento for inválido em relação à sua definição de tipo ou tiver uma validade desconhecida, o elemento também será inválido ou de validade desconhecida.
Considerando que a validade de um elemento depende da validade de seus elementos filhos e de seus atributos, qualquer modificação em um ou outro irá alterar a validade do elemento, caso ele fosse válido anteriormente. Especificamente, se os elementos filho ou atributos de um elemento forem inseridos, atualizados ou excluídos, a validade do elemento se tornará desconhecida. Isso é representado pela Validity propriedade da propriedade do SchemaInfo elemento que está sendo definida como NotKnown. Além disso, esse efeito se propaga recursivamente para cima em todo o documento XML, pois a validade do elemento pai (e do pai desse elemento, e assim por diante) também se torna desconhecida.
Para obter mais informações sobre a validação de esquema e a XPathNavigator classe, consulte Validação de Esquema usando XPathNavigator.
Modificando atributos
Os métodos SetValue e SetTypedValue podem ser usados para modificar nós de atributo não tipados e tipados, bem como os outros tipos de nó listados na seção "Modificando nós".
O exemplo a seguir altera o valor do genre atributo do primeiro book elemento no books.xml arquivo.
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 obter mais informações sobre os métodos SetValue e SetTypedValue, consulte as seções "Modificando valores não tipados" e "Modificando valores tipados".
Propriedades "InnerXml" e "OuterXml"
As propriedades InnerXml e OuterXml da classe XPathNavigator alteram a marcação XML dos nós em que um objeto XPathNavigator está atualmente posicionado.
A InnerXml propriedade altera a marcação XML dos nós filho no qual um objeto XPathNavigator está atualmente posicionado, com o conteúdo analisado do XML string fornecido. Da mesma forma, a OuterXml propriedade altera a marcação XML dos nós filho em que o objeto XPathNavigator está atualmente posicionado, bem como do próprio nó atual.
O exemplo a seguir usa a OuterXml propriedade para modificar o valor do price elemento e inserir um novo discount atributo no primeiro book elemento no contosoBooks.xml arquivo.
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);
O exemplo usa o contosoBooks.xml arquivo como uma 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>
Modificando nós de namespace
No DOM (Modelo de Objeto de Documento), as declarações de namespace são tratadas como se fossem atributos regulares que podem ser inseridos, atualizados e excluídos. A XPathNavigator classe não permite essas operações em nós de namespace porque alterar o valor de um nó de namespace pode alterar a identidade dos elementos e atributos no escopo do nó do namespace, conforme ilustrado no exemplo a seguir.
<root xmlns="http://www.contoso.com">
<child />
</root>
Se o exemplo XML acima for alterado da maneira a seguir, isso renomeará efetivamente cada elemento no documento porque o valor do URI do namespace de cada elemento será alterado.
<root xmlns="urn:contoso.com">
<child />
</root>
A inserção de nós de namespace que não entram em conflito com declarações de namespace no escopo em que são inseridas é permitida pela XPathNavigator classe. Nesse caso, as declarações de namespace não são declaradas em escopos inferiores no documento XML e não resultam na renomeação conforme ilustrado no exemplo a seguir.
<root xmlns:a="http://www.contoso.com">
<parent>
<a:child />
</parent>
</root>
Se o exemplo XML acima for alterado da seguinte maneira, as declarações de namespace serão propagadas corretamente no documento XML abaixo do escopo da outra declaração de namespace.
<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>
No exemplo XML acima, o atributo a:parent-id é inserido no parent elemento no http://www.contoso.com/parent-id namespace. O CreateAttribute método é usado para inserir o atributo enquanto está posicionado no parent elemento. A http://www.contoso.com declaração de namespace é inserida automaticamente pela XPathNavigator classe para preservar a consistência do restante do documento XML.
Modificando nós de referência de entidade
Nós de referência de entidade em um objeto XmlDocument são somente leitura e não podem ser editados usando as classes XPathNavigator ou XmlNode. Qualquer tentativa de modificar um nó de referência de entidade resulta em um InvalidOperationException.
Modificando elementos xsi:nil
A recomendação de esquema XML W3C apresenta o conceito de que um elemento é anulável. Quando um elemento é anulável, é possível que o elemento não tenha conteúdo e ainda seja válido. O conceito de um elemento ser nulável é semelhante ao conceito de um objeto ser null. A principal diferença é que um null objeto não pode ser acessado de forma alguma, enquanto um xsi:nil elemento ainda tem propriedades como atributos que podem ser acessados, mas não tem conteúdo (elementos filho ou texto). A existência do atributo xsi:nil com um valor de true em um elemento de um documento XML é usada para indicar que um elemento não tem conteúdo.
Se um XPathNavigator objeto for usado para adicionar conteúdo a um elemento válido com um xsi:nil atributo com um valor de true, o valor de seu xsi:nil atributo será definido como false.
Observação
Se o conteúdo de um elemento com um atributo xsi:nil definido como false for excluído, o valor do atributo não será alterado para true.
Salvando um documento XML
Salvar alterações feitas em um XmlDocument objeto como resultado dos métodos de edição descritos neste tópico é executado usando os métodos da XmlDocument classe. Para obter mais informações sobre como salvar alterações feitas em um XmlDocument objeto, consulte Salvar e escrever um documento.