Geoserver users,

Below is a write-up of a problem I've encountered using app-schemas when
specifying a mapping for an element whose attributes should be chosen
dynamically. I'm also posting a solution that works for me. I would like to
ask if anyone knows a simpler way to archive the same. Please let me know
if I should include more information.

Kind Regards,
Lazar

----------------------

# Geoserver 2.4.4 App-Schema Mapping

## Questions

1. What is the simplest way to generate an element that should sometimes
have an xlink:href attribute and sometimes have an xsi:nil attribute, where
the choice is data-driven?
2. As a last resort, is fiddling with geoserver's private cache of XSD
files an accepted technique for coercing it to produce required output?

## Problem and workaround involving xlink:href and xsi:nil

### Requirement

Generate

    <gsmlga:eventProcess xsi:nil="true" nilReason="missing">

or

    <gsmlga:eventProcess xlink:href="
http://resource.geoscience.gov.au/classifier/ga/eventprocess/deposition";
xlink:title="deposition">

### Solution

App-schema mapping

    <AttributeMapping>

<targetAttribute>gsml:relatedFeature/gsmlga:GeologicHistory/gsml:relatedFeature/gsmlga:GeologicEvent/gsmlga:eventProcess</targetAttribute>
       <ClientProperty>
          <name>xlink:href</name>
          <value>if_then_else(isNull(EVENTPROCESS_URI), Expression.NIL,
EVENTPROCESS_URI)</value>
       </ClientProperty>
       <ClientProperty>
          <name>xlink:title</name>
          <value>if_then_else(isNull(EVENTPROCESS_URI), Expression.NIL,
EVENTPROCESS)</value>
       </ClientProperty>
    </AttributeMapping>
    <AttributeMapping>

<targetAttribute>gsml:relatedFeature/gsmlga:GeologicHistory/gsml:relatedFeature/gsmlga:GeologicEvent/gsmlga:eventProcess</targetAttribute>
       <encodeIfEmpty>true</encodeIfEmpty>
       <ClientProperty>
          <name>xsi:nil</name>
          <value>if_then_else(isNull(EVENTPROCESS_URI), 'true',
Expression.NIL)</value>
       </ClientProperty>
       <ClientProperty>
          <name>nilReason</name>
          <value>if_then_else(isNull(EVENTPROCESS_URI), 'missing',
Expression.NIL)</value>
       </ClientProperty>
    </AttributeMapping>

Target element is `gsmlgu:GeologicUnit`. The schemas are

    xmlns:gml="http://www.opengis.net/gml/3.2";
    xmlns:gsml="http://xmlns.geosciml.org/GeoSciML-Core/3.2";
    xmlns:gsmlga="http://xmlns.geosciml.org/GeologicAge/3.2";

The above mapping works when `EVENTPROCESS_URI` is not null, but otherwise,
it generates

    <gsmlga:eventProcess xlink:href="#null" xsi:nil="true"
nilReason="missing"/>

In fact, even the following mapping


<AttributeMapping>


<targetAttribute>gsml:relatedFeature/gsmlga:GeologicHistory/gsml:relatedFeature/gsmlga:GeologicEvent/gsmlga:eventProcess</targetAttribute>


</AttributeMapping>


generates

    <gsmlga:eventProcess xlink:href="#null"/>

Since the above mapping is so minimal, I think that geoserver decides to
insert the xlink:href attribute based on something it sees in the
definition of eventProcess (where else?
it's not the mapping and it's not the data). Here is the definition from
geologicAge.xsd

    <element maxOccurs="unbounded" minOccurs="1" name="eventProcess"
nillable="true" type="gml:ReferenceType">
       <annotation>
          <appinfo>
             <gml:targetElement>gsmlga:EventProcessTerm</gml:targetElement>
          </appinfo>
          <documentation>The eventProcess specifies the process or
processes that occurred during the event. Examples include deposition,
extrusion, intrusion, cooling.</documentation>
       </annotation>
    </element>

Drilling further into the types, however, shows that xlink:href is not a
required attribute.

When I change this definition, in my app-schema-cache, to

    <element maxOccurs="unbounded" minOccurs="1" name="eventProcess"
nillable="true"> <!-- the type is gone -->
       <annotation>
          <appinfo>
             <gml:targetElement>gsmlga:EventProcessTerm</gml:targetElement>
          </appinfo>
          <documentation>The eventProcess specifies the process or
processes that occurred during the event. Examples include deposition,
extrusion, intrusion, cooling.</documentation>
       </annotation>
    </element>

the mapping works as required. Now that eventProcess can be of any type,
geoserver cannot infer that it should insert a null xlink:href attribute
into the generated element. Why does it in the first place?

### Note

The problem goes away if the requirements are changed to generate


    <gsmlga:eventProcess xlink:href="
http://www.opengis.net/def/nil/OGC/0/missing"; xlink:title="missing"/>


or



    <gsmlga:eventProcess xlink:href="
http://resource.geoscience.gov.au/classifier/ga/eventprocess/deposition";
xlink:title="deposition">

and not use xsi:nil attribute at all. The mapping becomes straightforward.

    <AttributeMapping>

<targetAttribute>gsml:relatedFeature/gsmlga:GeologicHistory/gsml:relatedFeature/gsmlga:GeologicEvent/gsmlga:eventProcess</targetAttribute>
       <ClientProperty>
          <name>xlink:href</name>
          <value>EVENTPROCESS_URI</value>
       </ClientProperty>
       <ClientProperty>
          <name>xlink:title</name>
          <value>EVENTPROCESS</value>
       </ClientProperty>
    </AttributeMapping>



Kind Regards,
Lazar
------------------------------------------------------------------------------
_______________________________________________
Geoserver-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geoserver-users

Reply via email to