Pergunta

I'm unmarshalling some XML from OGC and running into a problem where not all of the elements make it into the final object.

Here is the example XML

  <?xml version="1.0"?>
    <wfs:CreateStoredQuery xmlns:wfs="http://www.opengis.net/wfs/2.0"
    xmlns:fes="http://www.opengis.org/fes/2.0" xmlns:gml="http://www.opengis.net/gml/3.2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:myns="http://www.someserver.com/myns"
    xsi:schemaLocation="http://www.opengis.net/wfs/2.0
http://schemas.opengis.net/wfs/2.0/wfs.xsd"
    service="WFS" version="2.0.0">
         <wfs:StoredQueryDefinition id="urn:StoredQueries:FeaturesInPolygon">
        <wfs:Title>Features In Polygon</wfs:Title>
        <wfs:Abstract>Find all the features in a Polygon.</wfs:Abstract>
        <wfs:Parameter name="AreaOfInterest" type="gml:PolygonType" />
        <wfs:QueryExpressionText returnFeatureTypes="myns:Parks"
            language="urn:ogc:def:queryLanguage:OGC-WFS::WFS_QueryExpression"
            isPrivate="false">
            <wfs:Query typeNames="myns:Parks">
                <fes:Filter>
                    <fes:Within>
                        <fes:ValueReference>geometry</fes:ValueReference>
                        <gml:Polygon>
                            <gml:exterior>
                                <gml:LinearRing>
                                    <gml:posList>0 0 100 0 100 100 0 100 0 0</gml:posList>
                                </gml:LinearRing>
                            </gml:exterior>
                        </gml:Polygon>
                    </fes:Within>
                </fes:Filter>
            </wfs:Query>
        </wfs:QueryExpressionText>
    </wfs:StoredQueryDefinition>
</wfs:CreateStoredQuery>

Here is the XSD for the offending region

<xsd:complexType name="StoredQueryDescriptionType">
    <xsd:sequence>
        <xsd:element ref="wfs:Title" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="wfs:Abstract" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="ows:Metadata" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element name="Parameter"
            type="wfs:ParameterExpressionType"
            minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element name="QueryExpressionText"
            type="wfs:QueryExpressionTextType"
            minOccurs="1" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attribute name="id" type="xsd:anyURI" use="required"/>
</xsd:complexType>
<xsd:complexType name="ParameterExpressionType">
    <xsd:sequence>
        <xsd:element ref="wfs:Title" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="wfs:Abstract" minOccurs="0" maxOccurs="unbounded"/>
        <xsd:element ref="ows:Metadata" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
    <xsd:attribute name="name" type="xsd:string" use="required"/>
    <xsd:attribute name="type" type="xsd:QName" use="required"/>
</xsd:complexType>
<xsd:complexType name="QueryExpressionTextType" mixed="true">
    <xsd:choice>
        <xsd:any namespace="##other" processContents="skip"
            minOccurs="0" maxOccurs="unbounded"/>
        <xsd:any namespace="##targetNamespace" processContents="skip"
            minOccurs="0" maxOccurs="unbounded"/>
    </xsd:choice>
    <xsd:attribute name="returnFeatureTypes"
        type="wfs:ReturnFeatureTypesListType" use="required"/>
    <xsd:attribute name="language" type="xsd:anyURI" use="required"/>
    <xsd:attribute name="isPrivate" type="xsd:boolean" default="false"/>
</xsd:complexType>
<xsd:simpleType name="ReturnFeatureTypesListType">
    <xsd:list itemType="xsd:QName"/>
</xsd:simpleType>

The part that is messing up is the xsd:any under QueryExpressionTextType. It has the attribute processContents="skip" which causes JAXB to create DOM objects instead of the JAXB classes. I figured I would just use the JAXB context to unmarshall the DOM Nodes afterwards, here is some example code for what I tried.

public static void main(String[] args) throws Exception {
    InputStream in = new FileInputStream("test/res/createQuery.xml");
    JAXBContext context = JAXBContext.newInstance(
            net.opengis.gml.v_3_2_1.ObjectFactory.class,
            net.opengis.wfs.v_2_0_0.ObjectFactory.class,
            net.opengis.filter.v_2_0_0.ObjectFactory.class);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    JAXBElement<?> jElem = (JAXBElement<?>) unmarshaller.unmarshal(in);
    CreateStoredQueryType create = (CreateStoredQueryType) jElem.getValue();
    List<StoredQueryDescriptionType> descriptions = create
            .getStoredQueryDefinition();
    StoredQueryDescriptionType desc = descriptions.get(0);
    List<QueryExpressionTextType> texts = desc.getQueryExpressionText();
    QueryExpressionTextType text = texts.get(0);
    List<Object> contents = text.getContent();
    Node node = (Node) contents.get(0);
    jElem = (JAXBElement<?>) unmarshaller.unmarshal(node);
    QueryType query = (QueryType) jElem.getValue();
    // prints[{http://www.someserver.com/myns}Parks]
    System.out.println(query.getTypeNames());
    // is false
    System.out.println(query.isSetAbstractSelectionClause());
}

It gets the Query object out just fine (including the typeNames attribute). But it skips the Filter object. The Filter object inherits from AbstractSelectionClause, so it should be set in the returned object, but it isn't. I debugged and checked the DOM Element and confirmed that the Filter is in the DOM tree.

To get the JAXB objects I'm using, I checked out the SVN repository from the jvnet OGC project, I did have to compile the WFS 2.0 schemas, but the Filter and GML schemas were already done.

Any insight would be greatly appreciated.

Foi útil?

Solução

The example XML came from the OGC WFS 2.0 specification document (09-025r1) on page 81. There is a typo that has the xmlns for Filter as "http://www.opengis.org/fes/2.0" when is should be "http://www.opengis.net/fes/2.0". JAXB was seeing this as an unrecognized element and dropping it on the floor.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top