Reputation: 15
I am using System.Xml.Linq in order to get the information I need from this XML file. I need to end up with a List of the referenceId's that have the correct entityType in the child element.
Here is a sample of the XML file I am working with.
<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>
This is the best Linq query I can come up with, but it doesn't return anything. Nothing seems to work as soon as I try to query the attributes
var bindings = xElement.Elements("PropertySetBindings")
.Elements("PropertySetBind")
.Where(x => x.Elements("Rules")
.Elements("Include")
.Attributes("entityType").FirstOrDefault().Equals("IfcBeam"))
.Select(x => x.Attribute("referenceId"));
I think this might have to do with accessing the value of the attribute. There is no property for Attributes("entityType").Value Also, if I try to simply return all the "entityType" attributes, it returns the name and value of the attribute:
I think this query is complex for a couple reasons.
Let me know if anyone knows how to do this type of Linq query.
Upvotes: 0
Views: 628
Reputation: 377
Found this solution:
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);
Upvotes: 0
Reputation: 15
Okay, I found a working solution! I can only get it to work with using this query notation (I think its called) instead of the Lambda notation. This allows for accessing the value of the attribute.
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;
Let me know if you have a more elegant solution to this problem.
Upvotes: 0
Reputation: 12786
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);
It works as follows:
PropertySetBindings
elementPropertySetBind
childrenRules
elements, that have Include
elements that have entityType
attributes, that have a value of 'IfcBeam'.PropertySetBind
elements, select the 'referenceId' attributeUpvotes: 1