65.9K
CodeProject 正在变化。 阅读更多。
Home

LINQtoXML

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.33/5 (9投票s)

2012年1月26日

CPOL

6分钟阅读

viewsIcon

31973

使用 .NET 中的 LINQ 进行 XML 编程入门

本文档包含什么?

本文档概述了如何使用 LINQ 创建和查询 XML。本文档提供了我们在使用 LINQ to XML 时遇到的实际场景,并附有代码片段和易于理解的输出屏幕截图。

谁可以阅读?

所有有兴趣探索如何在 .NET 中使用 LINQ 来处理 XML 的人。

这对我有何用?

本文档不深入讨论所有主题,但肯定会为您提供一个快速入门指南,帮助您开始使用 LINQ to XML。

LINQ:Language Integrated Query 是一个 Microsoft .NET Framework 组件,它为 .NET 语言添加了原生的查询功能。

什么是 LINQ to XML:一个内存 XML 编程接口,使我们能够直接在 .NET Framework 编程语言中使用 XML。

LINQ to XML 的优势:与 LINQ 集成,使我们能够对内存中的 XML 文档编写查询,以检索元素和属性的集合。这些 LINQ 查询在语法上与 XPath 不同,但功能相似。

轻松地将查询结果用作 XElement XAttribute 对象构造函数的参数,从而以简单的方式创建 XML 树,这进一步使得 XML 树能够轻松地从一种形状转换为另一种形状。

为了使用 LINQ to XML,需要在代码中包含的命名空间System.Xml.Linq

从 .NET 3.5 开始,使用 LINQ (Language Integrated Query) 可以轻松地在 .NET 中创建 XML。以下是创建 XML 文档时的一些重要语法更改。

.NET 旧版本的 XML .NET 3.5 及更高版本的 XML
XMLDocument XDocument
XMLElement XElement
XMLAttribute XAttribute
XMLNamespace XNamespace
XMLNode XNode

创建简单的 XML

我们正在创建一个 XDocument (本质上就是一个 XML),其中包含 Employee 详细信息,如 NameId Designation

XDocument document = new XDocument(
                new XElement("Employees",
                    new XElement("Name", "Krishna"),
                    new XElement("ID", "12345"),
                    new XElement("Designation", "Engineer")));

如上面的代码片段所示,这就像引用 KEY、VALUE 对一样简单,就像 `new XElement("Name", "Krishna")` 一样。

输出是:

image001.jpg

创建带有元素属性的 XML

在大多数实际场景中,我们需要创建带有 Element 属性的 XML。以下是创建带有其职位作为 Element 属性的 Employees XML 的代码。

XDocument xDocument = new XDocument(
                new XElement("Employees",
                    new XElement("Employee", "Pavan",
                        new XAttribute("Designation", "Developer")),
                        new XElement("Employee", "sudhir",
                            new XAttribute("Designation", "Tester"))));

输出

image002.jpg

创建带有命名空间的 XML

使用命名空间创建 XDocument 时,必须显式地将命名空间添加到子元素中 `(new XElement(myNamespace + "Employee", "sudhir")`,以便它包含在父元素的命名空间中,如下所示。

XNamespace myNamespace = "https://www.microsoft.com";
XDocument xDocument = new XDocument(
                new XElement(myNamespace + "Employees",
                    new XElement(myNamespace + "Employee", "Pavan",
                        new XAttribute("Designation", "Developer")),
                        new XElement(myNamespace + "Employee", "sudhir",
                            new XAttribute("Designation", "Tester"))));

输出将如下所示

image003.jpg

如果您在添加子元素时未指定命名空间关键字(此处为“myNamespace”),则输出将如下所示

image004.jpg

正如用红色圆圈标出的那样,所有子元素中都会出现一个空的属性。因此,在创建 XDocument 时,需要为每个子元素附加命名空间。

处理多个命名空间

某些场景要求我们在创建的 XDocument 中有多个命名空间。一个命名空间用于父节点,另一个用于所有子节点。在这种情况下,我们需要使用两个不同的 XNamespace 变量,如下所示。

XNamespace firstNamespace = "https://www.microsoft.com";
XNamespace secondNamespace = "https://www.microsoft.com/myBlogs";

XDocument myDocument = new XDocument(
                new XElement(firstNamespace + "Employees",
                    new XElement(firstNamespace + "Employee", "Senthil"),
                    new XElement(firstNamespace + "Employee", "Prabhu"),
                    new XElement(secondNamespace + "Employee", "Sampath"),
                    new XElement(secondNamespace + "Employee", "Kumar")));

输出

image005.jpg

命名空间前缀

如果我们看上面的例子,输出中每个 Child 元素都带有命名空间 URL,看起来很乱。为了解决这个问题,我们可以将第二个命名空间也包含在父元素中,并为其分配一个关键字,然后在使用关键字创建 XElements

XDocument myDocument = new XDocument(
                new XElement(firstNamespace + "Employees",
                    new XAttribute(XNamespace.Xmlns +"secondNamespace",secondNamespace),
                    new XElement(firstNamespace + "Employee", "Senthil"),
                    new XElement(firstNamespace + "Employee", "Prabhu"),
                    new XElement(secondNamespace + "Employee", "Sampath"),
                    new XElement(secondNamespace + "Employee", "Kumar")));

输出

image006.jpg

保存 XML

我们可以将创建的 XDocument 保存到任何位置,作为 XML 文档。

XDocument xDoc = new XDocument(
                new XElement("Friends",
                    new XElement("Friend", "Senthil"),
                    new XElement("Friend", "Prabhu")));

            xDoc.Save(@"c:\myTest.xml"); 

当我们在浏览器中打开保存的 XML 时,可以看到如下所示的内容

image007.png

加载已保存的 XML

我们可以使用以下代码片段加载已保存的 XML 文档并创建 XDocument 。这里我加载 XML 文档,然后将生成的 XDocument 绑定到一个 string 变量。

XDocument myDoc = XDocument.Load(@"c:\myTest.xml");
string check = myDoc.ToString();

在文本可视化工具中检查 string 变量时,它看起来如下

image008.png

XElement 类的方法

Attribute, Attributes, Element, Elements, Descendants, Ancestors.

有很多方法,这里无法一一列举。我们将介绍如何使用一些最常用的方法,例如上面提到的那些。

  • Element:提供直接的子节点。
  • Elements:根据文档顺序提供此元素或文档的子元素集合。
  • Descendants:提供所有子节点。
  • Attributes:返回此元素的属性集合。
  • Attribute:返回具有指定 XNameXElement XAttribute

获取具有特定名称的元素

XDocument myDocument = new XDocument(
                new XElement("Employees",
                    new XAttribute(XNamespace.Xmlns +"secondNamespace",secondNamespace),
                    new XElement(firstNamespace + "Employee", "Senthil"),
                    new XElement(firstNamespace + "Employee", "Prabhu"),
                    new XElement(secondNamespace + "Employee", "Sampath"),
                    new XElement(secondNamespace + "Employee", "Kumar")));

            foreach (XElement myElement in myDocument.Descendants
            (firstNamespace + "Employee"))
            {
               String sOne += (string)myElement;
            }

foreach 语句用于循环遍历为 Element “Employee” 返回的所有值,然后将这些值分配给一个 string 变量。在将 Element 值分配给 string 变量时需要进行显式转换。输出如下:

image009.jpg

同样,我们可以使用以下查询获取 Element 属性值。

foreach (XElement myElement in xdoc.Descendants("Employee"))
{
    foreach (XAttribute xAtt in myElement.Attributes())
    {
        String sTwo = (string)xAtt;
    }
}

解析字符串到 XDocument

考虑一个包含 XML 的 string ,如下所示。

image010.png
string myString =
                @"<?xml version=""1.0"" encoding=""utf-8""?>
                <BankDetails>
                    <AccountHolder>Sai Krishna</AccountHolder>
                    <AccountNumber>12345678912</AccountNumber>
                    <AccountType>Savings</AccountType>
                </BankDetails>";

现在,调用 Parse 方法以从上述 string 生成 XDocument

XDocument myXDoc = XDocument.Parse(myString);

输出

image011.jpg

在 XDocument 上使用查询运算符

假设我们需要从以下 XDocument 中获取所有指导“Action”类型电影的 Director 姓名。

XDocument xdoc = new XDocument(
               new XElement("Directors",
                   new XElement("Director", "James cameron",
                       new XAttribute("Type", "Sci-Fi")),
                       new XElement("Director", "Guy Ritchie",
                           new XAttribute("Type", "Action")),
                               new XElement("Director", "clientEastwood",
                                   new XAttribute("Type", "Action")),
                                   new XElement("Director", "ManiRatnam",
                                       new XAttribute("Type", "Sci-Fi"))));

我们需要编写的查询

var myDirectors = from xE in xdoc.Descendants("Director")
                              where xE.Attribute("Type").Value == "Action"
                              orderby xE.Value
                              select xE.Value;
            foreach (var Director in myDirectors)
            {
                Console.WriteLine(Director);
            }

输出

我们得到“Client Eastwood”和“Guy Ritchie”,因为他们的类型属性是“Action”。

image012.png

将元素追加到已存在的 XDocument

假设已经创建了一个 XDocument 。我们需要向现有的 XDocument 添加几个额外的元素。例如,我们需要将另外两个员工的详细信息添加到已有的 Employee XML 树中。这里的代码向您展示了如何做到这一点。

XDocument myDoc = new XDocument(
               new XElement("SASTeam",
                   new XElement("Employee",
                   new XElement("Designer", "Naveen"),
                   new XElement("DBA", "Shankar")
                   )));

如果我们检查这个 XDocument,我们会得到下面的 XML 树。

现在,添加另外两个 employee 详细信息,如下所示。

myDoc.Root.Element("Employee").Add(
                new XElement("Developer", "Kaipa"),
                new XElement("Tester", "Kartheek"));

输出是:

image013.png

您会在输出中看到,已将两个员工的详细信息“Kaipa”和“kartheek”添加到了现有的 Employee 树中。

XDocument 和 String

考虑上一节中提到的 XDocument 。我们可以通过调用 Tostring() 方法将其转换为 XML 字符串。

string myString = myDoc.ToString();

结果 string 值为

myString =
"<SASTeam>\r\n  <Employee>\r\n    <Designer>Naveen</Designer>\r\n    
<DBA>Shankar</DBA>\r\n    <Developer>Kaipa</Developer>\r\n    
<Tester>Kartheek</Tester>\r\n  </Employee>\r\n</SASTeam>"

我注意到这与我们期望的不符。为了删除特殊字符,如“\r\n”,在将 XDocument 分配给 string 时,我们需要这样做。

string myString = myDoc.ToString(SaveOptions.DisableFormatting);

结果 string 如下所示。

myString =
"<SASTeam><Employee><Designer>Naveen</Designer><DBA>Shankar</DBA>
<Developer>Kaipa</Developer><Tester>Kartheek</Tester></Employee></SASTeam>"

默认的 SaveOption 是 None (SaveOptions.None)。我们需要根据需要切换选项。

XDeclaration 问题

如果在上一节中观察到,XDocument 中没有 XDeclaration 。这次我们将创建相同的 XDocument,但包含 XDeclaration

XDocument myDoc = new XDocument(
                new XDeclaration("1.0","utf-8","yes"),
                   new XElement("SASTeam",
                       new XElement("Employee",
                       new XElement("Designer", "Naveen"),
                       new XElement("DBA", "Shankar")
                   )));

现在,如果我们检查 myString,我们会得到

在结果 string 中,我们可以看到 XML 声明丢失了。为了解决这个问题,我们需要显式地附加声明 string ,如下所示。

image014.png
string myString = myDoc.Declaration.ToString() +
myDoc.ToString(SaveOptions.DisableFormatting);

现在 string 值是

image015.jpg

摘要

LINQ to XML 是使用最新的 .NET 框架语言功能构造、编写、读取和查询 XML 数据的新方法。这个新的 API 简化了 XML 的使用,并提供了卓越的开发体验。

© . All rights reserved.