首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于父节点属性获取子节点

基于父节点属性获取子节点
EN

Stack Overflow用户
提问于 2011-05-08 06:45:36
回答 2查看 2.2K关注 0票数 2

我有一个XML格式的CrystalReport报告(对不起,我删除了大部分示例数据)。

代码语言:javascript
复制
<?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查询来提取基于父节点的FieldName属性的值节点,并将其放入对象中。FormattedReportObject节点的值或父节点没有唯一的属性。到目前为止,这是我的代码。

代码语言:javascript
复制
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.Xml.Linq.XElement”的查询表达式中的后续from子句中不允许使用“System.Xml.Linq.XElement”类型的表达式。类型推断在调用‘SelectMany’时失败)

或者,如果我没有得到一个错误,我最终什么也检索不到。对于改进我的查询,任何建议都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-05-08 12:34:50

您的代码有几个问题。首先,编译器抱怨的是,正如@MizardX所提到的,您正在使用fo.Element("Value"),就好像它是序列一样。您可能想要的是编写let e = fo.Element("Value") (或者跳过这个部分,直接编写select fo.Element("Value").Value)。

另一个问题是,您的XML正在使用名称空间,但您没有使用,这意味着您应该创建一个XNamespace对象,并在任何有元素名称的地方使用它。

此外,您的代码的编写方式,AircraftType是一个字符串序列。我想这不是你想要的。

考虑到您希望对不同的FieldName值执行相同的操作,您可能希望将它变成一个方法。

有了上面提到的所有问题,代码应该如下所示:

代码语言:javascript
复制
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();
票数 2
EN

Stack Overflow用户

发布于 2011-05-08 12:11:58

fo.Element("Value")返回一个XElement-object。您想要的可能是fo.Elements("Value") (请注意复数's')。

错误消息抱怨它不知道如何迭代XElement对象。

您没有得到任何结果的原因是XML-文件使用的是名称空间。若要查找默认命名空间之外的元素,需要在节点名称之前加上名称空间的前缀。

我还注意到,您没有使用fos变量,因此没有必要使用该循环。fs.Decendants()已经给出了正确的结果。

代码语言:javascript
复制
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();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5926035

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档