XML 字面量
XML 文本允许您在代码中使用 XML 语法。通过这种方式处理 XML 文件非常简单,因为您可以在代码中看到标签,并且比传统方法更快地访问信息。
这是我之前在我的博客上发布的一些文章的英文版本。XML 文本是处理 XML 文件的绝佳方式,但社区的使用率不如其应有的那么高。

引言
XML 文本允许您在代码中使用 XML 语法。通过这种方式处理 XML 文件非常简单,因为您可以在代码中看到标签,并且比使用 XmlDocument 和 XmlElement 的传统方法更快地访问信息。它位于 System.Xml.Linq 命名空间中,自 .NET Framework 3.5/Visual Studio 2008(仅适用于 Visual Basic)以来,它支持大多数 可扩展标记语言 (XML) 1.0 规范,并且与 Lambda 表达式和/或 LINQ 一起,为您提供了更好的 XML 文件处理体验。它也支持智能感知,并自动缩进代码。
XML 字面量
注意:大多数示例都使用了 Option Infer On,但您可以声明正确的数据类型。基本概念如下所示
Dim msg = <msg>
This is a test!
This is a test!
</msg>.Value
MessageBox.Show(msg, "XML Literals")
这将显示一个 MessageBox
,保留空格、制表符和换行符。请注意,它不需要行延续字符“_”(在 Visual Studio 2010 中,对于大多数代码,这甚至是不必要的)。

您可以创建运行时 XML 文件。以下是如何实现的示例
Dim bookList = _
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- List of books and magazines -->
<library>
<books>
<book name="The Hunger Games " author="Suzanne Collins"/>
<book name="Breaking Dawn" author="Stephenie Meyer"/>
<book name="The Last Song" author="Nicholas Sparks"/>
</books>
<magazine>
<magazineName>"MSDN Magazine"</magazineName>
<magazineName>"Code Magazine"</magazineName>
</magazine>
</library>
变量 bookList
现在是一个 XDocument,您可以像处理 XML 文件一样对其进行操作。要将文件保存到磁盘,只需使用 Save()
方法即可
bookList.Save("c:\library.xml")
读取信息
前面的示例生成了一个简单的 XML 文件并将其保存到磁盘。要加载文件并进行处理,您可以使用 Load()
事件。这将加载文件并显示杂志名称,使用 Descendants 属性,该属性允许从 XElement 或 XDocument 对象按名称访问子节点。
Dim xmlFile = XDocument.Load("c:\library.xml")
Debug.WriteLine(xmlFile...<magazineName>.Value)
这将在 Immediate Window 中显示“MSDN Magazine”,因为它找到的第一个名称。我们还可以使用 Lambda 表达式获取第二本杂志(在本例中)。
Dim xmlFile = XDocument.Load("c:\library.xml")
Debug.WriteLine(xmlFile...<magazineName>.Where(Function(f) _
f.Value = "Code Magazine").Value)
这是针对“常规”节点元素,但如果您需要显示属性,则应使用以下语法
Dim xmlFile = XDocument.Load("c:\library.xml")
Debug.WriteLine(xmlFile...<book>.@author)
以及用于过滤特定值的 Lambda 表达式(这将搜索书名并显示作者姓名)
Dim xmlFile = XDocument.Load("c:\library.xml")
Debug.WriteLine(xmlFile...<book>.Where(Function(f) _
f.@name = "Breaking Dawn").@author)
列出信息
您有多种方式可以显示信息,例如循环遍历值、使用 LINQ to XML 或 Lambda 表达式。您可以这样列出所有杂志
For Each m In From element In bookList.<library>.<magazine>.<magazineName>
Debug.WriteLine(m.Value)
Next
您还可以使用 Descendants
属性,从而大大简化代码
For Each m In From element In bookList...<magazineName>
Debug.WriteLine(m.Value)
Next
要显示书名,您可以使用相同的方法,但由于现在处理的是属性,因此您使用“@
”来定义您想要的是属性,再加上属性名称。
For Each book In From element In bookList...<book>
Debug.WriteLine("Book: " & book.@name.ToString)
Debug.WriteLine("Author: " & book.@author.ToString)
' Separation line
Debug.WriteLine(New String("-"c, 40))
Next
但您也可以先过滤信息再显示。此示例使用 LINQ to XML 来检查所有书名中包含关键字“Song
”的书籍。
' Using LINQ to XML to filter the information
Dim bookSearch = From b In bookList...<book> _
Where b.@name.ToString.Contains("Song") _
Select b.@name, b.@author
' Show the results
For Each book In From element In bookSearch
Debug.WriteLine("Book: " & book.name)
Debug.WriteLine("Author: " & book.author)
' Separation line
Debug.WriteLine(New String("-"c, 40))
Next
嵌入式表达式
嵌入式表达式是在 XML 代码中使用的表达式,使用 <%= expression %>
标签,就像在 ASP.NET 中一样。您可以使用它们来构建或修改 XML 文件,这使得从 DataTable
、List(Of T)
、Dictionary
等创建文件变得非常容易。
这是一个非常直接的示例,使用 Func() 委托(Lambda 表达式)来添加两个值
Dim f As Func(Of Integer, Integer, Integer) = Function(x, y) x + y
Dim example = _
<test>
<value><%= f(125, 125).ToString() %></value >
</test>
结果将是。
<test>
<value>250</value>
</test>
如果您有其他数据源,例如 List(Of T)
,您可以使用嵌入式表达式将所有值列出到 XML 文件中
' Creates a list with some book names
Dim bookList As New List(Of String)
bookList.AddRange(New String() {"The Hunger Games", "Breaking Dawn", "The Last Song"})
' Creates the XML e saves it to disk
Dim newBookList1 = _
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<library>
<books>
<%= From b In bookList Select <book><%= b %></book> %>
</books>
</library>
newBookList1.Save("c:\result.xml")
这将是结果
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<library>
<books>
<book>The Hunger Games</book>
<book>Breaking Dawn</book>
<book>The Last Song</book>
</books>
</library>
使用嵌入式表达式的另一个示例是使用 DataTable
。在这种情况下,它将创建一个带有“name
”和“author
”属性的 XML 文件。
' For this example is created a DataTable manually but
' could be the result of a SQL query or stored procedure
Dim dt As New DataTable("Books")
dt.Columns.Add("Book", GetType(String))
dt.Columns.Add("Author", GetType(String))
dt.Rows.Add("The Hunger Games", "Suzanne Collins")
dt.Rows.Add("Breaking Dawn", "Stephenie Meyer")
dt.Rows.Add("The Last Song", "Nicholas Sparks")
Dim ds As New DataSet
ds.Tables.Add(dt)
' Creates the XML e with two attributes: "name" and "author"
Dim newBookList2 = _
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- my book list -->
<library>
<books>
<%= From b In ds.Tables("Books") Select _
<book name=<%= b.Item("Book") %>
author=<%= b.Item("Author") %>/> %>
</books>
</library>
' Saves it to disk
newBookList2.Save("c:\library.xml")
这将是结果
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<library>
<books>
<book name=" The Hunger Games" author="Suzanne Collins" />
<book name=" Breaking Dawn" author="Stephanie Meyer" />
<book name=" The Last Song" author="Nicholas Sparks" />
</books>
</library>
修改节点
要使用 XML 文本修改 XML 文件中的任何信息,只需读取文件、更改值,然后将其保存到磁盘。
这里有一个例子:
Dim xmlFile = XDocument.Load("c:\library.xml")
xmlFile...<magazineName>.Value = "New Value"
xmlFile.Save("c:\library.xml")
但使用这种方法,只会更改找到的第一个值。如果您需要更改特定值,就像您通常做的那样,您需要先过滤信息以指明要更改的值。
Dim xmlFile = XDocument.Load("c:\library.xml")
Dim element = xmlFile.<library>.<books>.<book>.Where(Function(f) _
f.@name = "The Last Song")
element.@author = "Jorge Paulino"
xmlFile.Save("c:\library.xml")
这将把书“The Last Song”的作者姓名从“Nicholas Sparks”更改为“Jorge Paulino”(这很棒!)。但同样,使用 Descendants
属性可以为您节省一些代码。
Dim xmlFile = XDocument.Load("c:\library.xml")
xmlFile...<book>.Where(Function(f) _
f.@name = "The Last Song").@author = "Jorge Paulino"
xmlFile.Save("c:\library.xml")
插入节点
要将新节点插入 XML 文件,您首先需要构建新元素(XElement
),然后将其添加到正确的位置。我们可以通过两种方式做到这一点
Dim xmlFile = XDocument.Load("c:\library.xml")
Dim element = New XElement("book", _
New XAttribute("name", "XML Literals"), _
New XAttribute("author", "Jorge Paulino"))
Dim parent = xmlFile...<books>.FirstOrDefault()
parent.Add(element)
xmlFile.Save("c:\library.xml")
或者,更简单的方式
Dim xmlFile = XDocument.Load("c:\library.xml")
Dim element = <book name="XML Literals" author="Jorge Paulino"/>
Dim parent = xmlFile...<books>.FirstOrDefault()
parent.Add(element)
xmlFile.Save("c:\library.xml")
在此示例中,我们可以使用前面看到的嵌入式表达式动态更改属性的值。
删除节点
删除节点与修改方法非常相似。您可以删除所有节点
Dim xmlFile = XDocument.Load("c:\library.xml")
xmlFile...<magazineName>.Remove()
xmlFile.Save("c:\library.xml")
或删除特定节点
Dim xmlFile = XDocument.Load("c:\library.xml")
xmlFile...<book>.Where(Function(f) f.@author = "Suzanne Collins").Remove()
xmlFile.Save("c:\library.xml")
最终示例(Web)
您还可以使用 XML 文本从 Web 读取信息,例如 RSS。此示例读取我的 个人博客 RSS,并按“VB.NET”类别(由标签定义)进行过滤。这显示了处理 XML 文本的强大功能和便捷性。
Dim xmlFile = XDocument.Load("http://feeds.feedburner.com/vbtuga")
Dim blogList = xmlFile...<item>.Where(Function(f) _
f.<category>.Value = "VB.NET").<title>.ToList()
For Each item As XElement In blogList
Console.WriteLine(item.Value)
Next
Console.ReadKey()
以及控制台结果
结论
XML 文本提供了多种处理 XML 文件的方法。如今,XML 文件无处不在(报告、配置、数据存储、RSS 等),能够快速、轻松地处理它们至关重要。
我希望本文能帮助您更好地掌握 XML 文本,并更多地使用它们!