需要撰寫 XML 編輯器、轉換系統或報表寫入器等程式的 LINQ to XML 開發人員,通常需要比元素和屬性更精細層級運作的程式代碼。 它們通常需要在節點層級操作,處理文字節點、指令碼和註解。 本文提供節點層級程序設計的相關信息。

範例:XDocument Parent 子節點的屬性值會設定為 null

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)

此範例會產生下列輸出:

範例:新增文字不一定建立新的文字節點

在數個 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())

此範例會產生下列輸出:

範例:將文字節點值設定為空字串並不會刪除節點

在某些 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 = _
    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)

此範例會產生下列輸出:

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的子節點時,會傳回空白文字節點。 不過,當您使用 XPath 軸方法遍歷 XDocument 的子節點時,將不會傳回空白文字節點。

// 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())

此範例會產生下列輸出:

XDocument 的 XML 宣告節點是屬性,而不是子節點

當您逐一查看 的 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 />