Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
LINQ para desenvolvedores XML que precisam escrever programas como um editor XML, um sistema de transformação ou um gravador de relatórios geralmente precisam de código que funcione em um nível mais fino de granularidade do que elementos e atributos. Eles geralmente precisam trabalhar no nível do nó, manipulando nós de texto, processando instruções e processando comentários. Este artigo fornece informações sobre programação no nível do nó.
Exemplo: Os Parent valores de propriedade dos nós filhos de XDocument são definidos como null
A propriedade Parent contém o elemento pai XElement, não o nó pai. Os filhos de XDocument não têm pai XElement. O progenitor é o documento, portanto, a Parent propriedade para esses nós é definida como null.
O exemplo a seguir demonstra isso:
XDocument doc = XDocument.Parse(@"<!-- a comment --><Root/>");
Console.WriteLine(doc.Nodes().OfType<XComment>().First().Parent == null);
Console.WriteLine(doc.Root.Parent == null);
Dim doc As XDocument = XDocument.Parse("<!-- a comment --><Root/>")
Console.WriteLine(doc.Nodes().OfType(Of XComment).First().Parent Is Nothing)
Console.WriteLine(doc.Root.Parent Is Nothing)
Este exemplo produz a seguinte saída:
True
True
Exemplo: Adicionar texto pode ou não criar um novo nó de texto
Em vários modelos de programação XML, os nós de texto adjacentes são sempre mesclados. Isso às vezes é chamado de normalização de nós de texto. LINQ to XML não normaliza nós de texto. Se você adicionar dois nós de texto ao mesmo elemento, isso resultará em nós de texto adjacentes. No entanto, se você adicionar conteúdo especificado como uma cadeia de caracteres em vez de como um XText nó, LINQ to XML pode mesclar a cadeia de caracteres com um nó de texto adjacente. O exemplo a seguir demonstra isso.
XElement xmlTree = new XElement("Root", "Content");
Console.WriteLine(xmlTree.Nodes().OfType<XText>().Count());
// this doesn't add a new text node
xmlTree.Add("new content");
Console.WriteLine(xmlTree.Nodes().OfType<XText>().Count());
// this does add a new, adjacent text node
xmlTree.Add(new XText("more text"));
Console.WriteLine(xmlTree.Nodes().OfType<XText>().Count());
Dim xmlTree As XElement = <Root>Content</Root>
Console.WriteLine(xmlTree.Nodes().OfType(Of XText)().Count())
' This doesn't add a new text node.
xmlTree.Add("new content")
Console.WriteLine(xmlTree.Nodes().OfType(Of XText)().Count())
'// This does add a new, adjacent text node.
xmlTree.Add(New XText("more text"))
Console.WriteLine(xmlTree.Nodes().OfType(Of XText)().Count())
Este exemplo produz a seguinte saída:
1
1
2
Exemplo: Atribuir a uma nodo de texto o valor de uma string vazia não elimina o nodo
Em alguns modelos de programação XML, é garantido que os nós de texto não contêm a cadeia de caracteres vazia. O raciocínio é que esse nó de texto não tem impacto na serialização do XML. No entanto, pela mesma razão que os nós de texto adjacentes são possíveis, se você remover o texto de um nó de texto definindo seu valor para a cadeia de caracteres vazia, o nó de texto em si não será excluído.
XElement xmlTree = new XElement("Root", "Content");
XText textNode = xmlTree.Nodes().OfType<XText>().First();
// the following line doesn't cause the removal of the text node.
textNode.Value = "";
XText textNode2 = xmlTree.Nodes().OfType<XText>().First();
Console.WriteLine(">>{0}<<", textNode2);
Dim xmlTree As XElement = <Root>Content</Root>
Dim textNode As XText = xmlTree.Nodes().OfType(Of XText)().First()
' The following line doesn't cause the removal of the text node.
textNode.Value = ""
Dim textNode2 As XText = xmlTree.Nodes().OfType(Of XText)().First()
Console.WriteLine(">>{0}<<", textNode2)
Este exemplo produz a seguinte saída:
>><<
Exemplo: Um elemento com um nó de texto vazio é serializado de forma diferente de um elemento sem nó de texto.
Se um elemento contiver apenas um nó de texto filho vazio, ele será serializado com a sintaxe de etiqueta longa: <Child></Child>. Se um elemento não contiver quaisquer nós filhos, ele será serializado com a sintaxe de etiqueta curta: <Child />.
XElement child1 = new XElement("Child1",
new XText("")
);
XElement child2 = new XElement("Child2");
Console.WriteLine(child1);
Console.WriteLine(child2);
Dim child1 As XElement = New XElement("Child1", _
New XText("") _
)
Dim child2 As XElement = New XElement("Child2")
Console.WriteLine(child1)
Console.WriteLine(child2)
Este exemplo produz a seguinte saída:
<Child1></Child1>
<Child2 />
Exemplo: Namespaces são atributos na árvore LINQ to XML
Embora as declarações de namespace tenham sintaxe idêntica aos atributos, em algumas interfaces de programação, como XSLT e XPath, as declarações de namespace não são consideradas atributos. No entanto, em LINQ to XML, namespaces são armazenados como XAttribute objetos na árvore XML. Caso faça uma iteração pelos atributos de um elemento que contém uma declaração de namespace, esta declaração será um dos itens presentes na coleção retornada. A IsNamespaceDeclaration propriedade indica se um atributo é uma declaração de namespace.
XElement root = XElement.Parse(
@"<Root
xmlns='http://www.adventure-works.com'
xmlns:fc='www.fourthcoffee.com'
AnAttribute='abc'/>");
foreach (XAttribute att in root.Attributes())
Console.WriteLine("{0} IsNamespaceDeclaration:{1}", att, att.IsNamespaceDeclaration);
Dim root As XElement = _
<Root
xmlns='http://www.adventure-works.com'
xmlns:fc='www.fourthcoffee.com'
AnAttribute='abc'/>
For Each att As XAttribute In root.Attributes()
Console.WriteLine("{0} IsNamespaceDeclaration:{1}", att, _
att.IsNamespaceDeclaration)
Next
Este exemplo produz a seguinte saída:
xmlns="http://www.adventure-works.com" IsNamespaceDeclaration:True
xmlns:fc="www.fourthcoffee.com" IsNamespaceDeclaration:True
AnAttribute="abc" IsNamespaceDeclaration:False
Exemplo: os métodos do eixo XPath não retornam os nós de texto filho do XDocument
LINQ to XML permite nós de texto filho de um XDocument, desde que os nós de texto contenham apenas espaço em branco. No entanto, o modelo de objeto XPath não inclui espaços em branco como nós descendentes de um documento, portanto, ao iterar pelos descendentes de um XDocument usando o eixo Nodes, os nós de texto de espaços em branco são retornados. No entanto, quando se realiza a iteração através dos filhos de um XDocument usando os métodos do eixo XPath, os nós de texto em espaço em branco não serão retornados.
// Create a document with some white space child nodes of the document.
XDocument root = XDocument.Parse(
@"<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<Root/>
<!--a comment-->
", LoadOptions.PreserveWhitespace);
// count the white space child nodes using LINQ to XML
Console.WriteLine(root.Nodes().OfType<XText>().Count());
// count the white space child nodes using XPathEvaluate
Console.WriteLine(((IEnumerable)root.XPathEvaluate("text()")).OfType<XText>().Count());
' Create a document with some white space child nodes of the document.
Dim root As XDocument = XDocument.Parse( _
"<?xml version='1.0' encoding='utf-8' standalone='yes'?>" & _
vbNewLine & "<Root/>" & vbNewLine & "<!--a comment-->" & vbNewLine, _
LoadOptions.PreserveWhitespace)
' Count the white space child nodes using LINQ to XML.
Console.WriteLine(root.Nodes().OfType(Of XText)().Count())
' Count the white space child nodes using XPathEvaluate.
Dim nodes As IEnumerable = CType(root.XPathEvaluate("text()"), IEnumerable)
Console.WriteLine(nodes.OfType(Of XText)().Count())
Este exemplo produz a seguinte saída:
3
0
O nó de declaração XML de um XDocument é uma propriedade, não um nó filho
Ao iterar pelos nós filhos de um XDocument, você não verá o objeto de declaração XML. É uma propriedade do documento, não um nó filho do mesmo.
XDocument doc = new XDocument(
new XDeclaration("1.0", "utf-8", "yes"),
new XElement("Root")
);
doc.Save("Temp.xml");
Console.WriteLine(File.ReadAllText("Temp.xml"));
// this shows that there is only one child node of the document
Console.WriteLine(doc.Nodes().Count());
Dim doc As XDocument = _
<?xml version='1.0' encoding='utf-8' standalone='yes'?>
<Root/>
doc.Save("Temp.xml")
Console.WriteLine(File.ReadAllText("Temp.xml"))
' This shows that there is only one child node of the document.
Console.WriteLine(doc.Nodes().Count())
Este exemplo produz a seguinte saída:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root />
1