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.
- Depth of the XML Tree (nested children).
- The need to use the attribute values.
Let me know if anyone knows how to do this type of Linq query.
CodePudding user response:
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:
- select the
PropertySetBindings
element - select the
PropertySetBind
children - filter the children to children with
Rules
elements, that haveInclude
elements that haveentityType
attributes, that have a value of 'IfcBeam'. - from those
PropertySetBind
elements, select the 'referenceId' attribute - check for null (attribute exists)
- select the value of the attribute (so you dont have the "referenceId=value", just the value)
CodePudding user response:
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.
CodePudding user response:
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);