private void CreatePropertyCondition(XbimQueryBuilder qBuilder, XmlNode propGroupNode) { GroupRule pGrpRule = GetGroupRule(propGroupNode); //apply logical operators according to the "select" XmlNodeList pSets = ((XmlElement)propGroupNode).GetElementsByTagName("propertySet"); foreach (XmlNode pSet in pSets) { string pSetName = GetName(pSet); NameRule pSetNameRule = GetNameRule(pSet); XmlNode propNode = ((XmlElement)pSet).GetElementsByTagName("property").Item(0); string propName = GetName(propNode); NameRule propNameRule = GetNameRule(propNode); if (string.IsNullOrEmpty(propName)) { errLog.WriteLine("Name of the property must be specified. Property set: '" + pSetName + "', element: '" + eName + "'."); continue; } XmlNode valNode = (propNode as XmlElement).GetElementsByTagName("value").Item(0); string value = valNode.InnerText; ValueRule valRule = GetValueRule(valNode); if (string.IsNullOrEmpty(value)) { errLog.WriteLine("Value of the property '" + propName + "' must be specified. Property set: '" + pSetName + "', element: '" + eName + "."); continue; } qBuilder.AddPropertyCondition(pSetName, pSetNameRule, propName, propNameRule, value, valRule, pGrpRule); } }
private void CreateAttributeCondition(XbimQueryBuilder qBuilder, XmlNode attributeGroupNode) { GroupRule grpRule = GetGroupRule(attributeGroupNode); //apply logical operators according to the "select" XmlNodeList attrs = ((XmlElement)attributeGroupNode).GetElementsByTagName("attribute"); foreach (XmlNode attr in attrs) { //attribute name XmlNode nameNode = ((XmlElement)attr).GetElementsByTagName("name").Item(0); if (nameNode == null) { errLog.WriteLine("Attribute with unspecified name in element '" + eName + "', group '" + grpName + "'"); continue; } string attName = nameNode.InnerText; PropertyInfo propInfo = elemType.GetProperty(attName); if (propInfo == null) { errLog.WriteLine("Attribute with name '" + attName + "' doesn't exist in the element '" + eName + "' in group '" + grpName + "'"); continue; } //attribut value XmlNode valueNode = ((XmlElement)attr).GetElementsByTagName("value").Item(0); if (nameNode == null) { errLog.WriteLine("Attribute with unspecified value in element '" + eName + "', group '" + grpName + "'"); continue; } string attValue = valueNode.InnerText; ValueRule attValRule = GetValueRule(valueNode); //create part of the expression qBuilder.AddAttributeCondition(attName, attValue, attValRule, grpRule); } }
/// <summary> /// Performs grouping based on the XML data provided. /// </summary> /// <param name="errLog">Stream for err output</param> /// <returns>True if grouping was successful. False otherwise.</returns> public bool PerformGrouping() { errLog = new StringWriter(); if (_xmlDoc == null) { errLog.WriteLine("No input XML data."); return false; } //get all group nodes XmlNodeList groups = _xmlDoc.GetElementsByTagName("group"); if (groups == null || groups.Count == 0) { errLog.WriteLine("No group rules in the XML document"); return false; } //clear groups from elements ClearGroups(_rootGroup); //create group for all non-grouped elements IfcGroup noGroup = GetGroup("No group"); if (noGroup == null) { noGroup = _model.Instances.New<IfcGroup>(gr => { gr.Name = "No group"; gr.Description = ""; }); _rootGroup.AddObjectToGroup(noGroup); } List<IfcElement> allElements = _model.Instances.OfType<IfcElement>().ToList(); List<IfcTypeObject> allTypes = _model.Instances.OfType<IfcTypeObject>().ToList(); foreach (XmlNode group in groups) { grpName = GetName(group); if (String.IsNullOrEmpty(grpName)) { errLog.WriteLine("Group without name detected. All information in this group specification will be skipped."); continue; } //search for the existing group with the same name (convert to upper case for the comparison) and create new group if none exists. IfcGroup iGroup = GetGroup(grpName); if (iGroup == null) { iGroup = _model.Instances.New<IfcGroup>(gr => gr.Name = grpName); _rootGroup.AddObjectToGroup(iGroup); } //process all ifc objects specified for the group XmlNodeList elements = ((XmlElement)group).GetElementsByTagName("element"); foreach (XmlNode element in group) { eName = GetName(element); if (String.IsNullOrEmpty(eName)) { errLog.WriteLine("Element without name detected in group '" + grpName + "'. This element will NOT be included in the"); continue; } //get elemType for reflection of attributes IfcType ifcType; if (!IfcMetaData.TryGetIfcType(eName, out ifcType)) continue; else elemType = ifcType.Type; XbimQueryBuilder qBuilder = new XbimQueryBuilder(elemType); //process all element attributes XmlNodeList attributeGroups = ((XmlElement)element).GetElementsByTagName("attributes"); //there could be different grouping rules for attribute rules inside (all, none, oneOf, any) foreach (XmlNode attrGroup in attributeGroups) { CreateAttributeCondition(qBuilder, attrGroup); } //process element properties XmlNodeList propertyGroups = ((XmlElement)element).GetElementsByTagName("properties"); //there could be different grouping rules for attribute rules inside (all, none, oneOf, any) foreach (XmlNode propGroup in propertyGroups) { CreatePropertyCondition(qBuilder, propGroup); } //element type processing IEnumerable<IPersistIfcEntity> types = null; XmlNodeList elTypeNodeList = (element as XmlElement).GetElementsByTagName("elementType"); foreach (XmlNode elTypeNode in elTypeNodeList) //there should be just one 'elTypeNode' { XbimQueryBuilder typeQueryBuilder = null; elTypeName = elTypeNode.InnerText; if (string.IsNullOrEmpty(elTypeName)) { errLog.WriteLine("Name of the element type is not specified for element of type '" + eName + "'. Element type conditions will not be applied. "); continue; } IfcType ifcTypeLookup; if (!IfcMetaData.TryGetIfcType(eName, out ifcTypeLookup)) continue; else elemType = ifcTypeLookup.Type; if (!typeof(IfcTypeObject).IsAssignableFrom(elemType)) { errLog.WriteLine("'" + elTypeName + "' is not type object."); continue; } typeQueryBuilder = new XbimQueryBuilder(elTypeName); //type attributes XmlNodeList typeAttrGroups = ((XmlElement)element).GetElementsByTagName("typeAttributes"); foreach (XmlNode typeAttrGrpNode in typeAttrGroups) { CreateAttributeCondition(typeQueryBuilder, typeAttrGrpNode); } //process element type properties XmlNodeList typePropGroups = ((XmlElement)element).GetElementsByTagName("typeProperties"); //there could be different grouping rules for attribute rules inside (all, none, oneOf, any) foreach (XmlNode propGroup in typePropGroups) { CreatePropertyCondition(typeQueryBuilder, propGroup); } types = _model.Instances.Where<IPersistIfcEntity>(typeQueryBuilder.BuildQuery()); break; } //get elements and element type IEnumerable<IPersistIfcEntity> instances = allElements.Where(qBuilder.BuildQuery().Compile()).ToList(); //check elements against element type (if defined) if (types != null) { instances = FilterElementsByType(instances, types); } //add result to the group foreach (var inst in instances) { IfcElement el = inst as IfcElement; if (el != null && allElements.Remove(el)) { IfcTypeObject type = el.GetDefiningType(); if (allTypes.Remove(type)) //ensure that it is not added twice iGroup.AddObjectToGroup(type); //get all elements of this type IEnumerable<IfcRelDefinesByType> rels = _model.Instances.Where<IfcRelDefinesByType>(r => r.RelatingType == type); foreach (var rel in rels) { IEnumerable<IfcElement> elemOfType = rel.RelatedObjects.OfType<IfcElement>(); foreach (var item in elemOfType) { allElements.Remove(item); } } //IfcObjectDefinition objDef = inst as IfcObjectDefinition; //if (objDef != null) iGroup.AddObjectToGroup(objDef); } } } } //fill the no-group group with elements which are not in any group foreach (IfcTypeObject element in allTypes) noGroup.AddObjectToGroup(element); return true; }
/// <summary> /// Performs grouping based on the XML data provided. /// </summary> /// <param name="errLog">Stream for err output</param> /// <returns>True if grouping was successful. False otherwise.</returns> public bool PerformGrouping() { errLog = new StringWriter(); if (_xmlDoc == null) { errLog.WriteLine("No input XML data."); return(false); } //get all group nodes XmlNodeList groups = _xmlDoc.GetElementsByTagName("group"); if (groups == null || groups.Count == 0) { errLog.WriteLine("No group rules in the XML document"); return(false); } //clear groups from elements ClearGroups(_rootGroup); //create group for all non-grouped elements IfcGroup noGroup = GetGroup("No group"); if (noGroup == null) { noGroup = _model.Instances.New <IfcGroup>(gr => { gr.Name = "No group"; gr.Description = ""; }); _rootGroup.AddObjectToGroup(noGroup); } List <IfcElement> allElements = _model.Instances.OfType <IfcElement>().ToList(); List <IfcTypeObject> allTypes = _model.Instances.OfType <IfcTypeObject>().ToList(); foreach (XmlNode group in groups) { grpName = GetName(group); if (String.IsNullOrEmpty(grpName)) { errLog.WriteLine("Group without name detected. All information in this group specification will be skipped."); continue; } //search for the existing group with the same name (convert to upper case for the comparison) and create new group if none exists. IfcGroup iGroup = GetGroup(grpName); if (iGroup == null) { iGroup = _model.Instances.New <IfcGroup>(gr => gr.Name = grpName); _rootGroup.AddObjectToGroup(iGroup); } //process all ifc objects specified for the group XmlNodeList elements = ((XmlElement)group).GetElementsByTagName("element"); foreach (XmlNode element in group) { eName = GetName(element); if (String.IsNullOrEmpty(eName)) { errLog.WriteLine("Element without name detected in group '" + grpName + "'. This element will NOT be included in the"); continue; } //get elemType for reflection of attributes IfcType ifcType; if (!IfcMetaData.TryGetIfcType(eName, out ifcType)) { continue; } else { elemType = ifcType.Type; } XbimQueryBuilder qBuilder = new XbimQueryBuilder(elemType); //process all element attributes XmlNodeList attributeGroups = ((XmlElement)element).GetElementsByTagName("attributes"); //there could be different grouping rules for attribute rules inside (all, none, oneOf, any) foreach (XmlNode attrGroup in attributeGroups) { CreateAttributeCondition(qBuilder, attrGroup); } //process element properties XmlNodeList propertyGroups = ((XmlElement)element).GetElementsByTagName("properties"); //there could be different grouping rules for attribute rules inside (all, none, oneOf, any) foreach (XmlNode propGroup in propertyGroups) { CreatePropertyCondition(qBuilder, propGroup); } //element type processing IEnumerable <IPersistIfcEntity> types = null; XmlNodeList elTypeNodeList = (element as XmlElement).GetElementsByTagName("elementType"); foreach (XmlNode elTypeNode in elTypeNodeList) //there should be just one 'elTypeNode' { XbimQueryBuilder typeQueryBuilder = null; elTypeName = elTypeNode.InnerText; if (string.IsNullOrEmpty(elTypeName)) { errLog.WriteLine("Name of the element type is not specified for element of type '" + eName + "'. Element type conditions will not be applied. "); continue; } IfcType ifcTypeLookup; if (!IfcMetaData.TryGetIfcType(eName, out ifcTypeLookup)) { continue; } else { elemType = ifcTypeLookup.Type; } if (!typeof(IfcTypeObject).IsAssignableFrom(elemType)) { errLog.WriteLine("'" + elTypeName + "' is not type object."); continue; } typeQueryBuilder = new XbimQueryBuilder(elTypeName); //type attributes XmlNodeList typeAttrGroups = ((XmlElement)element).GetElementsByTagName("typeAttributes"); foreach (XmlNode typeAttrGrpNode in typeAttrGroups) { CreateAttributeCondition(typeQueryBuilder, typeAttrGrpNode); } //process element type properties XmlNodeList typePropGroups = ((XmlElement)element).GetElementsByTagName("typeProperties"); //there could be different grouping rules for attribute rules inside (all, none, oneOf, any) foreach (XmlNode propGroup in typePropGroups) { CreatePropertyCondition(typeQueryBuilder, propGroup); } types = _model.Instances.Where <IPersistIfcEntity>(typeQueryBuilder.BuildQuery()); break; } //get elements and element type IEnumerable <IPersistIfcEntity> instances = allElements.Where(qBuilder.BuildQuery().Compile()).ToList(); //check elements against element type (if defined) if (types != null) { instances = FilterElementsByType(instances, types); } //add result to the group foreach (var inst in instances) { IfcElement el = inst as IfcElement; if (el != null && allElements.Remove(el)) { IfcTypeObject type = el.GetDefiningType(); if (allTypes.Remove(type)) //ensure that it is not added twice { iGroup.AddObjectToGroup(type); } //get all elements of this type IEnumerable <IfcRelDefinesByType> rels = _model.Instances.Where <IfcRelDefinesByType>(r => r.RelatingType == type); foreach (var rel in rels) { IEnumerable <IfcElement> elemOfType = rel.RelatedObjects.OfType <IfcElement>(); foreach (var item in elemOfType) { allElements.Remove(item); } } //IfcObjectDefinition objDef = inst as IfcObjectDefinition; //if (objDef != null) iGroup.AddObjectToGroup(objDef); } } } } //fill the no-group group with elements which are not in any group foreach (IfcTypeObject element in allTypes) { noGroup.AddObjectToGroup(element); } return(true); }