Hi Radek,
Thanks for your question. Given the in depth nature of your question, its probably best we follow up via our support system. I have created a new support case so you should receive an email shortly.
In the meantime, as you are fairly new to GML, I'll post a few links here for support resources in case you haven't seen them yet. While we don't have a generic GML tutorial yet, we do have a couple of related tutorials for AIXM and INSPIRE. As these readers/writers are based on the GML reader/writer, the basic principles are the same. So these examples should be helpful in terms of learning how to configure the GML writer. The AIXM article for example shows how to write to the dataset container - AIXMBasicMessage in this case and how to nest features using parent child gml ids.
https://knowledge.safe.com/articles/1312/aixm-xml-and-gml-formats-eu-airports-demo.html
https://knowledge.safe.com/articles/573/inspire-gml-reading-writing-and-validation-basics.html
https://docs.safe.com/fme/html/FME_Desktop_Documentation/FME_ReadersWriters/gml/GML_writer.htm
Dean
Hi Radek,
I've managed to put together a simple example that illustrates an approach to each of the 3 challenges listed above - see: geonamesgmlwriter2018.zip . You are still welcome to follow up via the support system for questions specific to your dataset and schema.
Question 1: How to expose and preserve or modify the FeatureCollection attributes.
By default, FME's GML writer tends to hide the FeatureCollection container object. However, the following approach will let you expose and preserve or modify it as needed.
First, make sure you set the GML or in this case the INSPIRE reader parameter gml:FeatureCollection to gml.
Next, you will need to import FeatureCollection feature type on both the reader and writer. You may need to set import featureType from schema not dataset. Once you have the FeatureCollection feature type, then on the writer you will need to set these GML writer parameters:
FeatureCollection: FeatureCollection
FeatureCollection ID: AT.HR.IT.0
FeatureCollection NS URI: http://www.opengis.net/gml/3.2
In my example, I'm using the GeographicalNames.xsd application schema which doesn't have any additional FeatureCollection attributes, so I enabled Map Predefined Properties to Yes so I could add a value for the gml_description field to the FeatureCollection object. Notice how each of the NamedPlace features have their gml_parent_id set to AT.HR.IT.0
Question 2: How to suppress null elements in the output
At present, the GML writer does not have a setting for suppressing null outputs. FME does support nillable, so if an attribute is nillable then FME will set xsi:nil=true for null values.
To suppress null writing <gml:name/> in this case, there are 2 possible workarounds. You can use the GMLFeatureComposer to generate the GML, then pass it through the XMLFormatter and set it to 'remove empty elements to Yes. You would then need to use the TextFileWriter to write out your GML.
My preferred approach is to stick with the GML writer, and use a NullAttributeMapper to detect null attributes and map them to 'missing'. This effectively removes the field from the FME feature schema. In the attached example I use the NullAttributeMapper to scan all attributes and map any empty or null attributes to missing. This picks up the gml_name{2} list element and effectively removes it from the list.
Question 3: How to set the default namespace to remove namespace prefix from the element names
In your case, you have <eczr:FeatureMember> and you want this to show up as just <FeatureMember >. To do that you need to make eczr the default namespace.
In my case I have <gn:NamedPlace>. If I want to remove the gn namespace prefix, I need to make the namespace associated with gn the default namespace. Looking at the namespace header of my output I see that:
xmlns:gn="urn:x-inspire:specification:gmlas:GeographicalNames:3.0"
So to remove this namespace we need to set:
Override XSD and Use Namespace Declarations to:
xmlns="urn:x-inspire:specification:gmlas:GeographicalNames:3.0"
Thereafter, the output will have <NamedPlace> not <gn:NamedPlace>
Hopefully this gives you a few things to try. Because you can't share your application schema, I thought it might be useful to have a basic example of GML writing to play with. The above example is based on the INSPIRE GeoNames article. Feel free to edit this workspace for testing purposes and send back your modified version if you run into trouble, or manage to reproduce a problem with it.
If you have questions specific to your data feel free to follow up via the support system.
Dean
Hi Radek,
I've managed to put together a simple example that illustrates an approach to each of the 3 challenges listed above - see: geonamesgmlwriter2018.zip . You are still welcome to follow up via the support system for questions specific to your dataset and schema.
Question 1: How to expose and preserve or modify the FeatureCollection attributes.
By default, FME's GML writer tends to hide the FeatureCollection container object. However, the following approach will let you expose and preserve or modify it as needed.
First, make sure you set the GML or in this case the INSPIRE reader parameter gml:FeatureCollection to gml.
Next, you will need to import FeatureCollection feature type on both the reader and writer. You may need to set import featureType from schema not dataset. Once you have the FeatureCollection feature type, then on the writer you will need to set these GML writer parameters:
FeatureCollection: FeatureCollection
FeatureCollection ID: AT.HR.IT.0
FeatureCollection NS URI: http://www.opengis.net/gml/3.2
In my example, I'm using the GeographicalNames.xsd application schema which doesn't have any additional FeatureCollection attributes, so I enabled Map Predefined Properties to Yes so I could add a value for the gml_description field to the FeatureCollection object. Notice how each of the NamedPlace features have their gml_parent_id set to AT.HR.IT.0
Question 2: How to suppress null elements in the output
At present, the GML writer does not have a setting for suppressing null outputs. FME does support nillable, so if an attribute is nillable then FME will set xsi:nil=true for null values.
To suppress null writing <gml:name/> in this case, there are 2 possible workarounds. You can use the GMLFeatureComposer to generate the GML, then pass it through the XMLFormatter and set it to 'remove empty elements to Yes. You would then need to use the TextFileWriter to write out your GML.
My preferred approach is to stick with the GML writer, and use a NullAttributeMapper to detect null attributes and map them to 'missing'. This effectively removes the field from the FME feature schema. In the attached example I use the NullAttributeMapper to scan all attributes and map any empty or null attributes to missing. This picks up the gml_name{2} list element and effectively removes it from the list.
Question 3: How to set the default namespace to remove namespace prefix from the element names
In your case, you have <eczr:FeatureMember> and you want this to show up as just <FeatureMember >. To do that you need to make eczr the default namespace.
In my case I have <gn:NamedPlace>. If I want to remove the gn namespace prefix, I need to make the namespace associated with gn the default namespace. Looking at the namespace header of my output I see that:
xmlns:gn="urn:x-inspire:specification:gmlas:GeographicalNames:3.0"
So to remove this namespace we need to set:
Override XSD and Use Namespace Declarations to:
xmlns="urn:x-inspire:specification:gmlas:GeographicalNames:3.0"
Thereafter, the output will have <NamedPlace> not <gn:NamedPlace>
Hopefully this gives you a few things to try. Because you can't share your application schema, I thought it might be useful to have a basic example of GML writing to play with. The above example is based on the INSPIRE GeoNames article. Feel free to edit this workspace for testing purposes and send back your modified version if you run into trouble, or manage to reproduce a problem with it.
If you have questions specific to your data feel free to follow up via the support system.
Dean
@DeanAtSafe the attached zip got lost (403) could you please re upload the zip? Thanks.
Hi Radek,
I've managed to put together a simple example that illustrates an approach to each of the 3 challenges listed above - see: geonamesgmlwriter2018.zip . You are still welcome to follow up via the support system for questions specific to your dataset and schema.
Question 1: How to expose and preserve or modify the FeatureCollection attributes.
By default, FME's GML writer tends to hide the FeatureCollection container object. However, the following approach will let you expose and preserve or modify it as needed.
First, make sure you set the GML or in this case the INSPIRE reader parameter gml:FeatureCollection to gml.
Next, you will need to import FeatureCollection feature type on both the reader and writer. You may need to set import featureType from schema not dataset. Once you have the FeatureCollection feature type, then on the writer you will need to set these GML writer parameters:
FeatureCollection: FeatureCollection
FeatureCollection ID: AT.HR.IT.0
FeatureCollection NS URI: http://www.opengis.net/gml/3.2
In my example, I'm using the GeographicalNames.xsd application schema which doesn't have any additional FeatureCollection attributes, so I enabled Map Predefined Properties to Yes so I could add a value for the gml_description field to the FeatureCollection object. Notice how each of the NamedPlace features have their gml_parent_id set to AT.HR.IT.0
Question 2: How to suppress null elements in the output
At present, the GML writer does not have a setting for suppressing null outputs. FME does support nillable, so if an attribute is nillable then FME will set xsi:nil=true for null values.
To suppress null writing <gml:name/> in this case, there are 2 possible workarounds. You can use the GMLFeatureComposer to generate the GML, then pass it through the XMLFormatter and set it to 'remove empty elements to Yes. You would then need to use the TextFileWriter to write out your GML.
My preferred approach is to stick with the GML writer, and use a NullAttributeMapper to detect null attributes and map them to 'missing'. This effectively removes the field from the FME feature schema. In the attached example I use the NullAttributeMapper to scan all attributes and map any empty or null attributes to missing. This picks up the gml_name{2} list element and effectively removes it from the list.
Question 3: How to set the default namespace to remove namespace prefix from the element names
In your case, you have <eczr:FeatureMember> and you want this to show up as just <FeatureMember >. To do that you need to make eczr the default namespace.
In my case I have <gn:NamedPlace>. If I want to remove the gn namespace prefix, I need to make the namespace associated with gn the default namespace. Looking at the namespace header of my output I see that:
xmlns:gn="urn:x-inspire:specification:gmlas:GeographicalNames:3.0"
So to remove this namespace we need to set:
Override XSD and Use Namespace Declarations to:
xmlns="urn:x-inspire:specification:gmlas:GeographicalNames:3.0"
Thereafter, the output will have <NamedPlace> not <gn:NamedPlace>
Hopefully this gives you a few things to try. Because you can't share your application schema, I thought it might be useful to have a basic example of GML writing to play with. The above example is based on the INSPIRE GeoNames article. Feel free to edit this workspace for testing purposes and send back your modified version if you run into trouble, or manage to reproduce a problem with it.
If you have questions specific to your data feel free to follow up via the support system.
Dean
Hello @DeanAtSafe, thanks for this comprehensive answer!
Question 1: How to expose and preserve or modify the FeatureCollection attributes.
This here is a bigger problem. I have tried your suggestion, it did not work. I have spent several hours trying to figure out what's wrong with my workspace. The problem that I had boils down to this issue: PostGIS dynamic writer forces lowercase attribute names
I have already reported this problem, it's known, and I can only hope that it gets fixed, because it seriously hinders my plans to do this dynamically, now with each xsd update I have to check, if there are any new attributes that are not lowercase
As you can see in the xsd snippet I have provided, all of the FeatureCollection attributes are snakeCase:
<xs:attribute name="constructionCode" type="xs:string" use="required"/>
<xs:attribute name="schemaVersion" type="xs:string" use="required"/>
<xs:attribute name="creatorName" type="xs:string" use="required"/>
<xs:attribute name="creatorVersion" type="xs:string" use="required"/>
<xs:attribute name="surveyedFrom" type="xs:date"/>
<xs:attribute name="surveyedTo" type="xs:date"/>
however when dynamically writing them do the database, they got converted to lowercase. Therefore when using xsd to map my data, those attributes didn't match, later failing validation.
Once I had renamed those columns in the database (which is still pretty bad solution), everything works.
Question 2: How to suppress null elements in the output
Even though I have not exposed any attributes, NullAttributeMapper set to map all attributes NULL -> Missing did the trick.
Question 3: How to set the default namespace to remove namespace prefix from the element names
Overriding XSD and using namespace declarations also solved my problem, very nice!
Now to hope that the dynamic writer issue gets fixed. :(
@DeanAtSafe the attached zip got lost (403) could you please re upload the zip? Thanks.
Thanks for noticing. Just re-loaded the attachment and tested it - looks fine now.