在实现LoST协议时,我们如何使用Java从findService请求解组大地位置?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在实现LoST协议时,我们如何使用Java从findService请求解组大地位置?相关的知识,希望对你有一定的参考价值。
我知道我对一个协议有一个非常具体的问题,世界上很少有人可能正在努力。提前感谢您阅读并试图帮助我。
上下文:我目前正在实现LoST:RFC 5222中描述的位置到服务转换协议。特别是,我正在解析一个XML文档的FindService请求。如果您感到好奇,可以在RFC中找到该文档的架构,但对此问题并不重要。
我正在使用Java和JAXB。我已经能够使用XSD实现各种请求而没有任何问题,所以我相信我的Maven插件和代码生成方法是正确的。
问题:我的问题是我在解组可以在FindService请求中找到的特定类型的位置时遇到问题。该类型是“geodetic-2d”位置类型,由以下附加文档定义:
GEOPRIV Presence Information Data Format Location Object (PIDF-LO) Usage Clarification, Considerations, and Recommendations geoshape profile
我得到的错误是javax.xml.bind.UnmarshalException:意外元素(uri:“http://www.opengis.net/pidflo/1.0”,local:“Circle”)。预期的元素是http://www.opengis.net/gml} ArcByCenterPoint> [...]
本消息的基本内容是unmarshaller期待来自gml命名空间的对象,但却找到了pidflo。 XML对象如下所示:
<gs:Circle srsName="urn:ogc:def:crs:EPSG::4326"
xmlns:gs="http://www.opengis.net/pidflo/1.0"
xmlns:gml="http://www.opengis.net/gml">
<gml:pos>
42.5463 -73.2512
</gml:pos>
<gml:radius uom="urn:ogc:def:uom:EPSG::9001">
850.24
</gml:radius>
</gs:Circle>
此示例来自OpenGIS文档,并且是正确的。请注意如何将两个名称空间混合在一起。 “Circle”确实来自pidflo名称空间,我已经验证了XSD是正确的。
问题:我想知道如何从查找服务“位置”对象解组大地位置。
为了简化这个问题,我想如果有人可以帮助我解组上面显示的Circle XML对象,我应该能够用其他类型来解决我的问题。
为了使这个问题更实用,请考虑以下代码:
public static void main(String[] args) {
JAXBContext gmlOrCivicContext = null;
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
gmlOrCivicContext = JAXBContext.newInstance(net.opengis.pidflo._1.CircleType.class);
Marshaller marshaller = gmlOrCivicContext.createMarshaller();
ObjectFactory objectFactory = new ObjectFactory();
JAXBElement<CircleType> circle = objectFactory.createCircle(new CircleType());
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(circle, byteArrayOutputStream);
String x = byteArrayOutputStream.toString();
System.out.println(x);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(x.getBytes());
Unmarshaller unmarshaller = gmlOrCivicContext.createUnmarshaller();
Object unmarshal = unmarshaller.unmarshal(byteArrayInputStream);
} catch (JAXBException e) {
e.printStackTrace();
}
}
运行这个程序时,我能够编组并打印出Circle对象,但是我无法解组它(即使我使用完全相同的上下文!)。
以下是上面显示的代码的控制台输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:Circle xmlns:ns1="http://www.opengis.net/gml" xmlns:ns2="http://www.opengis.net/pidflo/1.0"/>
javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.opengis.net/pidflo/1.0", local:"Circle"). Expected elements are <{http://www.opengis.net/gml}ArcByCenterPoint>,[...]
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:242)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:109)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1131)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:556)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:351)
at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:613)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3132)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:852)
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
有谁知道为什么我能够编组对象而不是解组它?
如果我能提供更多信息,请告诉我。
- 萨科
我找到了为什么我的JAXB生成的类可以编组XML而不是解组它的原因。我想我会在这里分享答案,以防有人在使用LoST(以及它使用的命名空间名称)的类似问题中运行。
问题出在opengis pidflo geoshape xml名称空间的生成包名称中:xmlns:gs =“http://www.opengis.net/pidflo/1.0”。
它会自动转换为以下java包名:net.opengis.pidflo._1.CircleType.class
“_1”中的前导下划线与Java不兼容。
修复包名后,所有代码都开始工作。
我更改了我的Maven JAXB插件配置,以使用“packageName”指令强制geoshape包避免使用下划线。我还在每个xsd的基础上分割代码生成,为每个代码设置正确的包,我使用clearOutputDir指令来避免每个执行过度重写彼此生成的输出。
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>xjc-gml</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>src/main/xsd/geoshape/0.1.0/GML-pidf-lo-shape.xsd</sources>
<packageName>net.opengis.pidflo</packageName>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
<execution>
<id>xjc-civic</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>src/main/xsd/civicAddr.xsd</sources>
<packageName>ietf.params.xml.ns.pidf.geopriv10.civicaddr</packageName>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
<execution>
<id>xjc-lost</id>
<goals>
<goal>xjc</goal>
</goals>
<configuration>
<sources>src/main/xsd/lost.xsd</sources>
<packageName>ietf.params.xml.ns.lost1</packageName>
<clearOutputDir>false</clearOutputDir>
</configuration>
</execution>
</executions>
</plugin>
问候,
- 萨科
以上是关于在实现LoST协议时,我们如何使用Java从findService请求解组大地位置?的主要内容,如果未能解决你的问题,请参考以下文章