OGCから一部の XML をアンマーシャリングしていて、すべての要素が最終的なオブジェクトになるわけではないという問題が発生しています。
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>
問題のあるリージョンの XSD は次のとおりです。
<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>
めちゃくちゃになっているのは、QueryExpressionTextType の下の xsd:any です。これには属性 processContents="skip" があり、JAXB は JAXB クラスの代わりに DOM オブジェクトを作成します。その後、JAXB コンテキストを使用して DOM ノードをアンマーシャリングするだけだと考えました。
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());
}
Query オブジェクトを正常に取得します (typeNames 属性を含む)。ただし、Filter オブジェクトはスキップされます。Filter オブジェクトは AbstractSelectionClause を継承しているため、返されるオブジェクトに設定する必要がありますが、そうではありません。DOM Element をデバッグして確認したところ、DOM ツリーに Filter があることを確認しました。
私が使用している JAXB オブジェクトを取得するために、jvnet OGC プロジェクトから SVN リポジトリをチェックアウトしました。WFS 2.0 スキーマをコンパイルする必要がありましたが、フィルターと GML スキーマは既に作成されていました。
どんな洞察も大歓迎です。