使用 Linq 分组 XML,层次结构不正确
Grouping XML with Linq, Hierarchy isn't right
我正在尝试研究如何在 asp.net C# 中从 sql 查询创建树视图菜单。作为学习练习,我有一个包含过去三年假期的数据库——我想创建一个树视图来显示按年份排序的假期。例如,"Year --> Holiday Name --> Holiday Date",其中“-->”表示层级。
无论如何,我正在使用此查询从 SQL 以 XML 文档的形式返回我的假期:
SELECT [Year], [Holiday], [Date] FROM [Database] FOR XML PATH('Holiday'), ROOT('Holidays')
这当然是 returns 一个没有分组的 XML 文档,所以我使用 Linq 按年份对我的假期进行分组,同时数据来自数据库,如下所示:
XmlReader reader = sqlCommand.ExecuteXmlReader();
if (reader.Read())
{
XElement doc = XElement.Load(reader);
var newData =
new XElement("Holidays",
from data in doc.Elements("Holiday")
group data by (int)data.Element("Year") into groupedData
select new XElement("Group",
new XAttribute("ID", groupedData.Key),
from g in groupedData
select new XElement("Holiday",
g.Element("Name"),
g.Element("Date")
)
)
);
这样更好:它按年对我的假期进行分组,但我的树视图最终看起来像这样:
2012
Holiday
Christmas Eve
12/24/12
Holiday
Christmas Day
12/25/12
Holiday
New Year's Eve
12/31/12
...等等。我是 Linq 的新手,所以我不太确定在这里做什么。我想摆脱那个 "Holiday" 级别并使实际日期成为假日名称的子节点。我无法对 SQL 查询执行任何操作,因为 XML 只能有一个根节点。有什么想法吗?
更改您的 select 语句...
select new XElement(
g.Element("Name").Value,
g.Element("Date")
)
由于您的树显然使用 XElement
的 ID
属性作为树节点标签,如果存在这样的属性,您可以将假日名称添加为 Holiday
节点,而不是作为嵌套属性:
if (reader.Read())
{
var doc = XElement.Load(reader);
var newData =
new XElement("Holidays",
from data in doc.Elements("Holiday")
group data by (int)data.Element("Year") into groupedData
select new XElement("Group",
new XAttribute("ID", groupedData.Key),
from g in groupedData
select new XElement("Holiday", new XAttribute("ID", g.Element("Name").Value), g.Element("Date"))
)
);
var newXml = newData.ToString();
Debug.WriteLine(newXml);
}
对于以下输入:
<?xml version="1.0" encoding="UTF-8"?>
<Holidays>
<Holiday>
<Name>Christmas Eve</Name>
<Date>12/24/12</Date>
<Year>2012</Year>
</Holiday>
<Holiday>
<Name>Christmas</Name>
<Date>12/25/12</Date>
<Year>2012</Year>
</Holiday>
<Holiday>
<Name>New Year's Eve</Name>
<Date>12/31/12</Date>
<Year>2012</Year>
</Holiday>
</Holidays>
这给出了以下输出:
<Holidays>
<Group ID="2012">
<Holiday ID="Christmas Eve">
<Date>12/24/12</Date>
</Holiday>
<Holiday ID="Christmas">
<Date>12/25/12</Date>
</Holiday>
<Holiday ID="New Year's Eve">
<Date>12/31/12</Date>
</Holiday>
</Group>
</Holidays>
(请注意,您不能将假期名称用作 XElement
名称,因为某些假期名称包含空格。)
我正在尝试研究如何在 asp.net C# 中从 sql 查询创建树视图菜单。作为学习练习,我有一个包含过去三年假期的数据库——我想创建一个树视图来显示按年份排序的假期。例如,"Year --> Holiday Name --> Holiday Date",其中“-->”表示层级。
无论如何,我正在使用此查询从 SQL 以 XML 文档的形式返回我的假期:
SELECT [Year], [Holiday], [Date] FROM [Database] FOR XML PATH('Holiday'), ROOT('Holidays')
这当然是 returns 一个没有分组的 XML 文档,所以我使用 Linq 按年份对我的假期进行分组,同时数据来自数据库,如下所示:
XmlReader reader = sqlCommand.ExecuteXmlReader();
if (reader.Read())
{
XElement doc = XElement.Load(reader);
var newData =
new XElement("Holidays",
from data in doc.Elements("Holiday")
group data by (int)data.Element("Year") into groupedData
select new XElement("Group",
new XAttribute("ID", groupedData.Key),
from g in groupedData
select new XElement("Holiday",
g.Element("Name"),
g.Element("Date")
)
)
);
这样更好:它按年对我的假期进行分组,但我的树视图最终看起来像这样:
2012
Holiday
Christmas Eve
12/24/12
Holiday
Christmas Day
12/25/12
Holiday
New Year's Eve
12/31/12
...等等。我是 Linq 的新手,所以我不太确定在这里做什么。我想摆脱那个 "Holiday" 级别并使实际日期成为假日名称的子节点。我无法对 SQL 查询执行任何操作,因为 XML 只能有一个根节点。有什么想法吗?
更改您的 select 语句...
select new XElement(
g.Element("Name").Value,
g.Element("Date")
)
由于您的树显然使用 XElement
的 ID
属性作为树节点标签,如果存在这样的属性,您可以将假日名称添加为 Holiday
节点,而不是作为嵌套属性:
if (reader.Read())
{
var doc = XElement.Load(reader);
var newData =
new XElement("Holidays",
from data in doc.Elements("Holiday")
group data by (int)data.Element("Year") into groupedData
select new XElement("Group",
new XAttribute("ID", groupedData.Key),
from g in groupedData
select new XElement("Holiday", new XAttribute("ID", g.Element("Name").Value), g.Element("Date"))
)
);
var newXml = newData.ToString();
Debug.WriteLine(newXml);
}
对于以下输入:
<?xml version="1.0" encoding="UTF-8"?>
<Holidays>
<Holiday>
<Name>Christmas Eve</Name>
<Date>12/24/12</Date>
<Year>2012</Year>
</Holiday>
<Holiday>
<Name>Christmas</Name>
<Date>12/25/12</Date>
<Year>2012</Year>
</Holiday>
<Holiday>
<Name>New Year's Eve</Name>
<Date>12/31/12</Date>
<Year>2012</Year>
</Holiday>
</Holidays>
这给出了以下输出:
<Holidays>
<Group ID="2012">
<Holiday ID="Christmas Eve">
<Date>12/24/12</Date>
</Holiday>
<Holiday ID="Christmas">
<Date>12/25/12</Date>
</Holiday>
<Holiday ID="New Year's Eve">
<Date>12/31/12</Date>
</Holiday>
</Group>
</Holidays>
(请注意,您不能将假期名称用作 XElement
名称,因为某些假期名称包含空格。)