Заметка
Доступ к этой странице требует авторизации. Вы можете попробовать войти в систему или изменить каталог.
Доступ к этой странице требует авторизации. Вы можете попробовать сменить директорию.
Разработчикам LINQ to XML, которые должны писать такие программы, как редактор XML, система преобразования или модуль записи отчетов, часто требуется код, который работает на более тонком уровне детализации, чем элементы и атрибуты. Они часто должны работать на уровне узла, манипулировать текстовыми узлами, обрабатывать инструкции и обрабатывать комментарии. В этой статье содержатся сведения о программировании на уровне узла.
Пример: Значения свойств дочерних узлов XDocument установлены в Parentnull.
Свойство Parent содержит родительский XElement, а не родительский узел. Дочерние XDocument узлы не имеют родительских XElementузлов. Документ является их родителем, поэтому свойство Parent для этих узлов установлено в null.
В следующем примере показано следующее:
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)
В примере получается следующий вывод.
True
True
Пример. Добавление текста может или не может создать новый текстовый узел
В ряде моделей программирования XML смежные текстовые узлы всегда объединяются. Иногда это называется нормализацией текстовых узлов. LINQ to XML не нормализует текстовые узлы. Если добавить два текстовых узла в один и тот же элемент, он приведет к смежным текстовым узлам. Однако, если содержимое указано в виде строки, а не в качестве узла XText, LINQ to XML может объединить строку с соседним текстовым узлом. Это продемонстрировано в следующем примере.
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())
В примере получается следующий вывод.
1
1
2
Пример. Установка значения текстового узла в пустую строку не удаляет узел
В некоторых моделях программирования XML текстовые узлы гарантированно не содержат пустую строку. Причина заключается в том, что такой текстовый узел не влияет на сериализацию XML. Однако по той же причине, что смежные текстовые узлы возможны, если удалить текст из текстового узла, задав его значение пустой строке, сам текстовый узел не будет удален.
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)
В примере получается следующий вывод.
>><<
Пример. Элемент с одним пустым текстовым узлом сериализуется по-разному от одного без текстового узла
Если элемент содержит только пустой дочерний текстовый узел, он сериализуется с использованием длинного синтаксиса тега: <Child></Child>. Если элемент не содержит дочерних узлов, он сериализован с синтаксисом короткого тега: <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)
В примере получается следующий вывод.
<Child1></Child1>
<Child2 />
Пример: Пространства имен используются как атрибуты в дереве LINQ to XML.
Несмотря на то что объявления пространства имен имеют идентичный синтаксис атрибутам, в некоторых интерфейсах программирования, таких как XSLT и XPath, объявления пространства имен не считаются атрибутами. Однако в LINQ to XML пространства имен хранятся в виде XAttribute объектов в дереве XML. Если вы выполняете итерацию по атрибутам элемента, содержащего объявление пространства имен, объявление пространства имен является одним из элементов в возвращаемой коллекции. Свойство IsNamespaceDeclaration указывает, является ли атрибут объявлением пространства имен.
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
В примере получается следующий вывод.
xmlns="http://www.adventure-works.com" IsNamespaceDeclaration:True
xmlns:fc="www.fourthcoffee.com" IsNamespaceDeclaration:True
AnAttribute="abc" IsNamespaceDeclaration:False
Пример. Методы оси XPath не возвращают дочерние текстовые узлы XDocument
LINQ to XML позволяет дочерним текстовым узлам элемента XDocument существовать, если текстовые узлы содержат только пробелы. Однако объектная модель XPath не включает пробелы в качестве дочерних узлов документа, поэтому при итерации по дочерним узлам XDocument с использованием оси Nodes будут возвращены текстовые узлы, представляющие пробелы. Однако при выполнении итерации через дочерние элементы XDocument с помощью методов оси XPath текстовые узлы, состоящие из пробелов, не будут возвращены.
// 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())
В примере получается следующий вывод.
3
0
Узел декларации XML в XDocument является свойством, а не дочерним узлом
При итерации по дочерним узлам объекта XDocumentне отображается объект объявления XML. Это свойство документа, а не его дочерний узел.
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())
В примере получается следующий вывод.
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Root />
1