Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

COBieLite Namespace #56

Open
simiii opened this issue Dec 11, 2020 · 10 comments
Open

COBieLite Namespace #56

simiii opened this issue Dec 11, 2020 · 10 comments

Comments

@simiii
Copy link

simiii commented Dec 11, 2020

I am converting an IFC-File into COBieLite like this:

                var cobieLiteHelper = new CoBieLiteHelper(ifcStore, null, null);
                var facilities = cobieLiteHelper.GetFacilities();

                using (TextWriter writer = File.CreateText("model.xml"))
                {
                    foreach (var facilityType in facilities) {
                        CoBieLiteHelper.WriteXml(writer, facilityType);
                    }
                }

the generated XML-File looks like the following using the core-namespace for everything except the facility.

<?xml version="1.0" encoding="utf-8"?>
<cobielite:Facility xmlns:core="http://docs.buildingsmartalliance.org/nbims03/cobie/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" core:externalEntityName="IfcBuilding" core:externalID="11000" core:externalSystemName="IFC text editor" xmlns:cobielite="http://docs.buildingsmartalliance.org/nbims03/cobie/cobielite">
  <core:FacilityName>01.1.A</core:FacilityName>
  <core:ProjectAssignment core:externalEntityName="IfcProject" core:externalID="100" core:externalSystemName="IFC text editor">
    <core:ProjectName>FM-A-01</core:ProjectName>
  </core:ProjectAssignment>
  <core:SiteAssignment core:externalEntityName="IfcSite" core:externalID="10010" core:externalSystemName="IFC text editor">
    <core:SiteName>FM Test Site</core:SiteName>
    <core:SiteDescription>Site object for testing Basic FM Handover</core:SiteDescription>
  </core:SiteAssignment>
  <core:FacilityDefaultLinearUnit>meters</core:FacilityDefaultLinearUnit>
  <core:FacilityDefaultAreaUnit>square meters</core:FacilityDefaultAreaUnit>
  <core:FacilityDefaultVolumeUnit>cubic meters</core:FacilityDefaultVolumeUnit>
  <core:FacilityDescription>Building object for testing Basic FM Handover</core:FacilityDescription>
  <core:Floors>
    <core:Floor core:externalEntityName="IfcBuildingStorey" core:externalID="20100" core:externalSystemName="IFC text editor">
      <core:FloorName>A.-1</core:FloorName>
      <core:FloorDescription>Kellergeschoss</core:FloorDescription>
      <core:FloorElevationValue>
        <core:DecimalValue>-3.2</core:DecimalValue>
      </core:FloorElevationValue>
      <core:FloorHeightValue />
    </core:Floor>
  </core:Floors>
</cobielite:Facility>

From the example clinik-file from https://www.nibs.org/page/bimc_cobielite I recognized that they use the cobielite-namespace instead of the core-namespace. Can I change the behaviour of the CoBieLiteHelper to use the cobielite-namespace? Is it a bug not using the cobielite-namespace as it provides more attributes for the elements in the xml?

Example: Can deserialize Attribute Value

<?xml version="1.0" encoding="utf-8"?>
<cobielite:Facility xmlns:core="http://docs.buildingsmartalliance.org/nbims03/cobie/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" core:externalEntityName="IfcBuilding" core:externalID="11000" core:externalSystemName="IFC text editor" xmlns:cobielite="http://docs.buildingsmartalliance.org/nbims03/cobie/cobielite">
  <core:FacilityName>01.1.A</core:FacilityName>
  <core:ProjectAssignment core:externalEntityName="IfcProject" core:externalID="100" core:externalSystemName="IFC text editor">
    <core:ProjectName>FM-A-01</core:ProjectName>
  </core:ProjectAssignment>
  <core:SiteAssignment core:externalEntityName="IfcSite" core:externalID="10010" core:externalSystemName="IFC text editor">
    <core:SiteName>FM Test Site</core:SiteName>
    <core:SiteDescription>Site object for testing Basic FM Handover</core:SiteDescription>
  </core:SiteAssignment>
  <core:FacilityDefaultLinearUnit>meters</core:FacilityDefaultLinearUnit>
  <core:FacilityDefaultAreaUnit>square meters</core:FacilityDefaultAreaUnit>
  <core:FacilityDefaultVolumeUnit>cubic meters</core:FacilityDefaultVolumeUnit>
  <core:FacilityDescription>Building object for testing Basic FM Handover</core:FacilityDescription>
  <core:FacilityAttributes>
    <cobielite:Attribute core:propertySetName="Pset_BuildingCommon">
      <core:AttributeName>YearOfConstruction</core:AttributeName>
      <core:AttributeCategory>Submitted</core:AttributeCategory>
      <core:AttributeValue>
        <core:AttributeStringValue>
          <core:StringValue>2002</core:StringValue>
        </core:AttributeStringValue>
      </core:AttributeValue>
    </cobielite:Attribute>
    <cobielite:Attribute core:propertySetName="Pset_BuildingCommon">
      <core:AttributeName>IsLandmarked</core:AttributeName>
      <core:AttributeCategory>Submitted</core:AttributeCategory>
      <core:AttributeValue>
        <core:AttributeBooleanValue />
      </core:AttributeValue>
    </cobielite:Attribute>
  </core:FacilityAttributes>
</cobielite:Facility>

Example: Cannot deserialize Attribute Value:

<?xml version="1.0" encoding="utf-8"?>
<cobielite:Facility xmlns:core="http://docs.buildingsmartalliance.org/nbims03/cobie/core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" core:externalEntityName="IfcBuilding" core:externalID="11000" core:externalSystemName="IFC text editor" xmlns:cobielite="http://docs.buildingsmartalliance.org/nbims03/cobie/cobielite">
  <core:FacilityName>01.1.A</core:FacilityName>
  <core:ProjectAssignment core:externalEntityName="IfcProject" core:externalID="100" core:externalSystemName="IFC text editor">
    <core:ProjectName>FM-A-01</core:ProjectName>
  </core:ProjectAssignment>
  <core:SiteAssignment core:externalEntityName="IfcSite" core:externalID="10010" core:externalSystemName="IFC text editor">
    <core:SiteName>FM Test Site</core:SiteName>
    <core:SiteDescription>Site object for testing Basic FM Handover</core:SiteDescription>
  </core:SiteAssignment>
  <core:FacilityDefaultLinearUnit>meters</core:FacilityDefaultLinearUnit>
  <core:FacilityDefaultAreaUnit>square meters</core:FacilityDefaultAreaUnit>
  <core:FacilityDefaultVolumeUnit>cubic meters</core:FacilityDefaultVolumeUnit>
  <core:FacilityDescription>Building object for testing Basic FM Handover</core:FacilityDescription>
  <core:FacilityAttributes>
    <core:Attribute core:propertySetName="Pset_BuildingCommon">
      <core:AttributeName>YearOfConstruction</core:AttributeName>
      <core:AttributeCategory>Submitted</core:AttributeCategory>
      <core:AttributeValue>
        <core:AttributeStringValue>
          <core:StringValue>2002</core:StringValue>
        </core:AttributeStringValue>
      </core:AttributeValue>
    </core:Attribute>
    <core:Attribute core:propertySetName="Pset_BuildingCommon">
      <core:AttributeName>IsLandmarked</core:AttributeName>
      <core:AttributeCategory>Submitted</core:AttributeCategory>
      <core:AttributeValue>
        <core:AttributeBooleanValue />
      </core:AttributeValue>
    </core:Attribute>
  </core:FacilityAttributes>
</cobielite:Facility>

Thanks for your help,
Simon

@andyward
Copy link
Member

Simon,

From what I can tell CobieLite defines its schema across 2 separate XSDs: core.xsd and cobielite.xsd, with the later referencing items in the former.

In your examples above, I think the only difference is that xbim is being explicit with the namespace; whereas the example COBieLite at https://portal.nibs.org/files/wl/?id=EAyFiAEke4wwmojNiVSo2GMwPZJYJdWy is setting core as the default namespace, and so omits core: from the elements

e.g. This is the start of the sample file

<?xml version="1.0" encoding="UTF-8"?>
<cobielite:Facility xmlns:cobielite="http://docs.buildingsmartalliance.org/nbims03/cobie/cobielite" 
xmlns="http://docs.buildingsmartalliance.org/nbims03/cobie/core" 
xmlns:core="http://docs.buildingsmartalliance.org/nbims03/cobie/core" 
core:externalEntityName="IfcBuilding" core:externalID="3eM8WbY_59RR5TDWry5aRU" core:externalSystemName="Autodesk Revit Architecture 2011" xsi:schemaLocation="http://docs.buildingsmartalliance.org/nbims03/cobie/cobielite cobielite.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <FacilityName>PN 0001</FacilityName>
  <FacilityCategory>11-13 24 14: Clinic</FacilityCategory>

... where FacilityName etc are implicitly in the core namespace.

Regarding the issue:

Looks to me that cobieLite:Attribute is correct. core.Attribute is the abstract super type, which is probably why it can't be deserialised.

What's the origin of the last CobieLite file in your issue? it looks wrong... Change the core.Attribute to cobielite:Attribute and it should work.

@simiii
Copy link
Author

simiii commented Dec 14, 2020

Hi thanks for your answer!

the last file in my issue is generated with xbim. If I change the namespace from core:Attribute to cobielite:Attribute it works fine as you suggest.

In my first example (xml also generated with xbim) the core:Floor should also be cobielite:Floor as the FloorElevationValue only exists for cobielite (see xsd) and not in core.

`

<xs:complexType name="FloorType">
	<xs:annotation>
		<xs:documentation>A minimum of one COBie.Floor record is required for all COBie deliverables containing spatial information.</xs:documentation>
	</xs:annotation>
	<xs:complexContent>
		<xs:extension base="core:FloorType">
			<xs:sequence>
				<xs:element ref="core:FloorCategory" minOccurs="0"/>
				<xs:element ref="core:FloorDescription" minOccurs="0"/>
				<xs:element ref="core:FloorElevationValue" minOccurs="0"/>
				<xs:element ref="core:FloorHeightValue" minOccurs="0"/>
				<xs:element ref="core:Spaces" minOccurs="0"/>
				<xs:element ref="core:FloorAttributes" minOccurs="0"/>
				<xs:element ref="core:FloorDocuments" minOccurs="0"/>
				<xs:element ref="core:FloorIssues" minOccurs="0"/>
			</xs:sequence>
		</xs:extension>
	</xs:complexContent>
</xs:complexType>
<xs:element name="Floor" type="cobielite:FloorType" substitutionGroup="core:Floor">
	<xs:annotation>
		<xs:documentation>A minimum of one COBie.Floor record is required for all COBie deliverables containing spatial information. </xs:documentation>
	</xs:annotation>
</xs:element>
<!--End Floor Related Content-->

`

I looked into your cobielite example file (Example File). There the attributes are also wrong marked with core.Attribute and not with cobieLite.Attribute.

Also interiesting: XmlSerializationCode.cs
if (needType) WriteXsiType(@"AttributeTypeBase", @"http://docs.buildingsmartalliance.org/nbims03/cobie/cobielite");
Somehow it seems to be possible to enable the correct namespace declaration.

@andyward
Copy link
Member

andyward commented Dec 16, 2020

Might need to loop in @CBenghi here as he touched this last (6 years ago!) - I'm not sure how that XmlSerialisationCode was generated - it doesn't look like standard xsd.exe generated code.

@simiii Can you describe what the actual issue is, for you and which part of your process is failing. Just to help test any fix. If you feel like digging in and putting a PR together as well that would be great. Apart from updating/PRs, I've not really been that involved in this codebase. I believe it came out of the NBS BIM Toolkit project

@CBenghi
Copy link
Member

CBenghi commented Dec 16, 2020 via email

@andyward
Copy link
Member

Hi Claudio

It was a long while ago so appreciate it may be distant memory but it was this commit 548301f

having looked at the full history it looks like you implemented the serialisation with sgen.exe

https://github.com/xBimTeam/XbimExchange/commits/master/Xbim.COBieLite/COBieLite%20Schema/XmlSerializationCode.cs

No worries if you can't remember!

@simiii
Copy link
Author

simiii commented Dec 16, 2020

I am trying to clarify my issue. I try to read an XML generated by XBIM with Java. I generated the Java-Classes with JAXB and the cobielite and core xsd files resulting in the classes below (simplified):

org.buildingsmartalliance.docs.nbims03.cobie.core.FloorType:

public class FloorType
    extends CobieRowType
{
    @XmlElement(name = "FloorName", required = true)
    protected String floorName;
}

org.buildingsmartalliance.docs.nbims03.cobie.cobielite:FloorType

public class FloorType extends org.buildingsmartalliance.docs.nbims03.cobie.core.FloorType
{
    // other fields left for simplicity
    @XmlElement(name = "FloorAttributes", namespace = "http://docs.buildingsmartalliance.org/nbims03/cobie/core")
    protected AttributeCollectionType floorAttributes;
}

Non processable XML generated by XBIM:

<?xml version="1.0" encoding="UTF-8"?>
<cobielite:Facility xmlns:cobielite="http://docs.buildingsmartalliance.org/nbims03/cobie/cobielite"
	 xmlns="http://docs.buildingsmartalliance.org/nbims03/cobie/core" 
	 xmlns:core="http://docs.buildingsmartalliance.org/nbims03/cobie/core" 
	 core:externalEntityName="IfcBuilding" 
	 core:externalID="1TB8MXxlf6BAI7EOFPDWY9" 
	 core:externalSystemName="Autodesk Revit Architecture 2012">
    <FacilityName>Test</FacilityName>
    <Floors>
        <Floor core:externalEntityName="IfcBuildingStorey" core:externalID="1TB8MXxlf6BAI7EOCcoVPF" core:externalSystemName="Autodesk Revit Architecture 2012">
            <FloorName>TestFloor</FloorName>
            <FloorCategory>FloorCategory</FloorCategory>
            <FloorDescription>FloorDescription</FloorDescription>
            <FloorElevationValue>
                <DecimalValue>12.0</DecimalValue>
            </FloorElevationValue>
            <FloorHeightValue>
                <DecimalValue>2700.0</DecimalValue>
            </FloorHeightValue>
        </Floor>
    </Floors>
</cobielite:Facility>

As you can see in the structure of the classes the attributes are only in org.buildingsmartalliance.docs.nbims03.cobie.cobielite.FloorType. If I read the XML generated by XBIM in JAVA, I only get the org.buildingsmartalliance.docs.nbims03.cobie.core.FloorType and not the subclass which results in the fact that I am unable to process the attributes in the floor.

If I manually change the namespace of the Floor to cobielite in the xml generated with xbim I can read the XML and get the subclass and therefore can read the attributes of the floor.

Processable XML generated by XBIM, manually edited:

<?xml version="1.0" encoding="UTF-8"?>
<cobielite:Facility xmlns:cobielite="http://docs.buildingsmartalliance.org/nbims03/cobie/cobielite"
	 xmlns="http://docs.buildingsmartalliance.org/nbims03/cobie/core" 
	 xmlns:core="http://docs.buildingsmartalliance.org/nbims03/cobie/core" 
	 core:externalEntityName="IfcBuilding" 
	 core:externalID="1TB8MXxlf6BAI7EOFPDWY9" 
	 core:externalSystemName="Autodesk Revit Architecture 2012">
    <FacilityName>Test</FacilityName>
    <Floors>
        <cobielite:Floor core:externalEntityName="IfcBuildingStorey" core:externalID="1TB8MXxlf6BAI7EOCcoVPF" core:externalSystemName="Autodesk Revit Architecture 2012">
            <FloorName>TestFloor</FloorName>
            <FloorCategory>FloorCategory</FloorCategory>
            <FloorDescription>FloorDescription</FloorDescription>
            <FloorElevationValue>
                <DecimalValue>12.0</DecimalValue>
            </FloorElevationValue>
            <FloorHeightValue>
                <DecimalValue>2700.0</DecimalValue>
            </FloorHeightValue>
        </cobielite:Floor>
    </Floors>
</cobielite:Facility>

@CBenghi
Copy link
Member

CBenghi commented Dec 16, 2020

Thanks @simiii,
this helps a lot, I understand the problem now.
I'll look into the details tomorrow and see if I can provide a solution.

@simiii
Copy link
Author

simiii commented Dec 17, 2020

I debugged through the code and found out, that xbim is absolutely fine with reading the xml with the core-namespace.
image

I created a test for reading the official example from nibs.com - the test fails as it is unable to read floors with cobielite-namespace.

        [TestMethod]
        public void CanReadSerialisedXmlWithCoreNamespace()
        {
            try
            {

                FacilityType facilityType1 = CoBieLiteHelper.ReadXml(@"Facility1.xml");
                Assert.AreEqual(4, facilityType1.Floors.LongCount());

            }
            catch (Exception ex)
            {
                while (ex.InnerException != null)
                {
                    Debug.WriteLine(ex.Message);
                    ex = ex.InnerException;
                }
                Debug.WriteLine(ex.Message);
                throw;
            }
        }

        [TestMethod]
        public void CanReadSerialisedXmlWithCobieLiteNamespace()
        {
            try
            {
                FacilityType facilityType2 = CoBieLiteHelper.ReadXml(@"Facility2.xml");
                Assert.AreEqual(5, facilityType2.Floors.LongCount());

            }
            catch (Exception ex)
            {
                while (ex.InnerException != null)
                {
                    Debug.WriteLine(ex.Message);
                    ex = ex.InnerException;
                }
                Debug.WriteLine(ex.Message);
                throw;
            }
        }

Should I be able to create and push a branch? I successfully cloned the repo.
Currently I get the following error message:

~/git/XbimExchange (56-COBieLite-Namespace)
$ git push --set-upstream origin 56-COBieLite-Namespace
ERROR: Permission to xBimTeam/XbimExchange.git denied to simiii.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

@andyward
Copy link
Member

I should create a Pull Request, which you can do from Visual Studio. But to be fair we can reproduce from your CanReadSerialisedXmlWithCobieLiteNamespace test above

@simiii
Copy link
Author

simiii commented Dec 17, 2020

In the zip file you find the Facility2.xml file.
Facility2.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants