提问人:Ryan Daley 提问时间:7/1/2022 最后编辑:MarkusRyan Daley 更新时间:7/1/2022 访问量:293
Linq to 根据嵌套子项的属性选择父项
Linq to Select a Parent based on Attribute of a Nested Child
问:
我正在使用 System.Xml.Linq 以便从此 XML 文件中获取我需要的信息。我需要最终得到一个在子元素中具有正确 entityType 的 referenceId 列表。
这是我正在使用的 XML 文件的示例。
<PropertySetBindings>
<PropertySetBind referenceId="assemblies">
<Rules>
<Include entityType="IfcElementAssembly" subtypes="true" />
</Rules>
</PropertySetBind>
<PropertySetBind referenceId="beam_common">
<Rules>
<Include entityType="IfcBeam" subtypes="false" />
</Rules>
</PropertySetBind>
<PropertySetBind referenceId="column_common">
<Rules>
<Include entityType="IfcColumn" subtypes="false" />
</Rules>
</PropertySetBind>
这是我能想到的最好的 Linq 查询,但它不返回任何内容。一旦我尝试查询属性,似乎没有任何效果
var bindings = xElement.Elements("PropertySetBindings")
.Elements("PropertySetBind")
.Where(x => x.Elements("Rules")
.Elements("Include")
.Attributes("entityType").FirstOrDefault().Equals("IfcBeam"))
.Select(x => x.Attribute("referenceId"));
我认为这可能与访问属性的值有关。没有 Attributes(“entityType”) 的属性。值 此外,如果我尝试简单地返回所有“entityType”属性,它将返回属性的名称和值:
我认为这个查询很复杂,有几个原因。
- XML 树的深度(嵌套子项)。
- 需要使用属性值。
如果有人知道如何进行这种类型的 Linq 查询,请告诉我。
答:
1赞
SynerCoder
7/1/2022
#1
var referenceIds = xElement.Element("PropertySetBindings")
.Elements("PropertySetBind")
.Where(x => x.Elements("Rules")
.Any(r => r.Elements("Include")
.Any(i => i.Attributes("entityType")
.Any(a => a.Value == "IfcBeam")
)
)
)
.Select(x => x.Attribute("referenceId"))
.Where(x => x != null)
.Select(x => x.Value);
其工作原理如下:
- 选择元素
PropertySetBindings
- 选择子项
PropertySetBind
- 将子元素筛选为具有元素的子元素,这些元素具有属性,值为“IfcBeam”。
Rules
Include
entityType
- 从这些元素中,选择“referenceId”属性
PropertySetBind
- 检查 null(属性存在)
- 选择属性的值(这样就没有“referenceId=value”,只有值)
评论
0赞
Ryan Daley
7/1/2022
谢谢!我从你的花哨裤子查询中学到了很多东西!
0赞
SynerCoder
7/1/2022
如果这对您有帮助,请考虑投赞成票,或将此答案标记为已接受。这是让社区看到这是一个很好的答案的简单方法。
0赞
Ryan Daley
7/1/2022
#2
好的,我找到了一个可行的解决方案! 我只能使用此查询表示法(我认为它被调用)而不是 Lambda 表示法来让它工作。这允许访问属性的值。
var bindings = from binding in xElement.Elements("PropertySetBindings")
from bind in binding.Elements("PropertySetBind")
from ru in bind.Elements("Rules")
from inc in ru.Elements("Include")
where (string)inc.Attribute("entityType") == "IfcBeam"
select bind.Attribute("referenceId").Value;
如果您对此问题有更优雅的解决方案,请告诉我。
0赞
Michalor
7/1/2022
#3
找到这个解决方案:
var bindings = xElement.Elements("PropertySetBindings")
.Elements("PropertySetBind")
.Where(x => x.Elements("Rules").FirstOrDefault()
.Elements("Include").FirstOrDefault()
.Attributes("entityType").FirstOrDefault().Value.Equals("IfcBeam"))
.Select(x => x.Attributes("referenceId").FirstOrDefault().Value);
评论
.Attributes("entityType").FirstOrDefault().Value == "IfcBeam")