我有一份XML格式的CrystalReport报告(很遗憾,我删除了大部分样本数据)
<?xml version="1.0" encoding="UTF-8" ?>
<FormattedReport xmlns = 'urn:crystal-reports:schemas' xmlns:xsi = 'http://www.w3.org/2000/10/XMLSchema-instance'>
<FormattedAreaPair Level="0" Type="Report">
<FormattedAreaPair Level="1" Type="Details">
<FormattedArea Type="Details">
<FormattedSections>
<FormattedSection SectionNumber="0">
<FormattedReportObjects>
<FormattedReportObject xsi:type="CTFormattedField" Type="xsd:string" FieldName="{AIRCRAFT.Tail Number}"><ObjectName>Field2</ObjectName>
<FormattedValue>C-FBCS</FormattedValue>
<Value>C-FBCS</Value>
</FormattedReportObject>
<FormattedReportObject xsi:type="CTFormattedField" Type="xsd:string" FieldName="{AIRCRAFT.Type ID}"><ObjectName>Field8</ObjectName>
<FormattedValue>DHC8</FormattedValue>
<Value>DHC8</Value>
</FormattedReportObject>
<FormattedReportObject xsi:type="CTFormattedField" Type="xsd:unsignedLong" FieldName="{TRIP LEGS.Trip Number}"><ObjectName>Field9</ObjectName>
<FormattedValue>68344</FormattedValue>
<Value>68344.00</Value>
</FormattedReportObject>
</FormattedReportObjects>
</FormattedSection>
</FormattedSections>
</FormattedArea>
</FormattedAreaPair>
<FormattedAreaPair Level="1" Type="Details">
<FormattedArea Type="Details">
<FormattedSections>
<FormattedSection SectionNumber="0">
<FormattedReportObjects>
<FormattedReportObject xsi:type="CTFormattedField" Type="xsd:string" FieldName="{AIRCRAFT.Tail Number}"><ObjectName>Field2</ObjectName>
<FormattedValue>C-FBCS</FormattedValue>
<Value>C-FBCS</Value>
</FormattedReportObject>
<FormattedReportObject xsi:type="CTFormattedField" Type="xsd:string" FieldName="{AIRCRAFT.Type ID}"><ObjectName>Field8</ObjectName>
<FormattedValue>DHC8</FormattedValue>
<Value>DHC8</Value>
</FormattedReportObject>
<FormattedReportObject xsi:type="CTFormattedField" Type="xsd:unsignedLong" FieldName="{TRIP LEGS.Trip Number}"><ObjectName>Field9</ObjectName>
<FormattedValue>68344</FormattedValue>
<Value>68344.00</Value>
</FormattedReportObject>
</FormattedReportObjects>
</FormattedSection>
</FormattedSections>
</FormattedArea>
</FormattedAreaPair>
...
</FormattedAreaPair>
</FormattedReport>
我正在尝试使用LINQ to XML查询来提取 Value 节点基于父节点的 FieldName 属性,并将它们放入对象中。 Value或FormattedReportObject节点的父节点没有唯一属性。到目前为止,这是我的代码
from fs in xDoc.Descendants("FormattedSection")
select new FlightSchedule
{
AircraftType = from fos in fs.Descendants("FormattedReportObjects")
from fo in fs.Descendants("FormattedReportObject")
where fo.Attribute("FieldName").Value.Equals("{AIRCRAFT.Type ID}")
from e in fo.Element("Value")
select e.Value),
....
};
我一直收到错误:
源类型为“System.Collections.Generic.IEnumerable”的查询表达式中的后续from子句中不允许使用类型为“System.Xml.Linq.XElement”的表达式。调用“SelectMany”时类型推断失败了
或者如果我没有收到错误,我最终没有检索到任何内容。在改进我的查询时,我们将非常感谢任何建议。
答案 0 :(得分:2)
您的代码有几个问题。首先,编译器抱怨的是,正如@MizardX所提到的那样,你正在使用fo.Element("Value")
,就像它是一个序列一样。你可能想要的是写let e = fo.Element("Value")
(或完全跳过这部分并直接写select fo.Element("Value").Value
)。
另一个问题是您的XML使用的是命名空间,但事实并非如此。这意味着您应该创建一个XNamespace
对象,并在有元素名称的地方使用它。
此外,代码的编写方式,AircraftType
是一系列字符串。我认为这不是你想要的。
看到你想为FieldName
的不同值做同样的事情,你可能想把它变成一个方法。
修复上述所有问题后,代码应如下所示:
static readonly XNamespace ns = XNamespace.Get("urn:crystal-reports:schemas");
string GetFieldValue(XElement fs, string fieldName)
{
return (from fo in fs.Descendants(ns + "FormattedReportObject")
where fo.Attribute("FieldName").Value == fieldName
let e = fo.Element(ns + "Value")
select e.Value).Single();
}
…
var flts = (from fs in xDoc.Descendants(ns + "FormattedSection")
select new FlightSchedule
{
AircraftType = GetFieldValue(fs, "{AIRCRAFT.Type ID}"),
…
}).ToList();
答案 1 :(得分:1)
fo.Element("Value")
返回XElement
- 对象。你想要的可能是fo.Elements("Value")
(注意复数'')。
错误消息是抱怨它不知道如何迭代XElement
对象。
您没有得到任何结果的原因是XML文件正在使用命名空间。要查找默认命名空间之外的元素,您需要在节点名称之前为命名空间添加前缀。
我还注意到你没有使用fos
变量,所以不需要循环。 fs.Decendants()
已经为您提供了正确的结果。
List<FlightSchedule> flts =
(from fs in xDoc.Descendants("{urn:crystal-reports:schemas}FormattedSection")
select new FlightSchedule
{
AircraftType =
(from fo in fs.Descendants("{urn:crystal-reports:schemas}FormattedReportObject")
where fo.Attribute("FieldName").Value == "{AIRCRAFT.Type ID}"
from e in fo.Elements("{urn:crystal-reports:schemas}Value")
select e.Value),
....
}).ToList();