JAXB 2(Oracle / Metro版本2.2.7,我也怀疑其他人)似乎不能容忍枚举元素中值的空格。
以下是最小的例子。 xmllint和Xerces都根据模式验证实例。令人费解的是,JAXB验证不会抱怨,但在尝试访问该值时会返回 null 。如何配置它以正确返回值?
更新:我已尝试根据建议here关联XmlAdapter
来修剪字符串,但结果是一样的。
更新II:这里是the ticket at Metro JAXB Jira。
<xs:schema targetNamespace="foo://a"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="foo://a">
<xs:element name="type" type="Type"/>
<xs:simpleType name="Type">
<xs:restriction base="xs:token">
<xs:enumeration value="Archive"/>
<xs:enumeration value="Organisation"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
<a:type xmlns:a="foo://a" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="foo://a A.xsd"
>Organisation </a:type>
(注意“组织”之后的空白)
public static void main(String args[]) throws Exception {
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
JAXBContext payloadContext = JAXBContext.newInstance("a");
Unmarshaller unmarshaller = payloadContext.createUnmarshaller();
unmarshaller.setSchema(schemaFactory.newSchema(new Source[]{new StreamSource(new FileInputStream(new File("A.xsd")))}));
JAXBElement<?> oUnmarshalled = (JAXBElement<?>) unmarshaller.unmarshal(new File("a.xml"));
Object o = oUnmarshalled.getValue(); // returns NULL
}
答案 0 :(得分:2)
当我使用JDK 1.7.0_21-b12中的JAXB实现为Mac运行以下代码时,我将获得enum值作为输出。
import javax.xml.XMLConstants;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
public class Demo {
public static void main(String args[]) throws Exception {
StreamSource xsd = new StreamSource("src/forum17114304/A.xsd");
StreamSource xml = new StreamSource("src/forum17114304/a.xml");
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(xsd);
schema.newValidator().validate(xml);
JAXBContext payloadContext = JAXBContext.newInstance("a");
Unmarshaller unmarshaller = payloadContext.createUnmarshaller();
unmarshaller.setSchema(schema);
JAXBElement<?> oUnmarshalled = (JAXBElement<?>) unmarshaller
.unmarshal(xml);
Object o = oUnmarshalled.getValue(); // returns ORGANISATION
System.out.println(o);
}
}
<强>输出强>
ORGANISATION
<强>更新强>
此用例中EclipseLink JAXB (MOXy)似乎存在错误:
此错误已在EclipseLink 2.5.1和2.6.0流中修复。每晚下载可从2013年6月15日开始的以下链接获取:
答案 1 :(得分:2)
因为(暂时)我想坚持使用JAXB RI(仅被“RI”部分吸引),最后我在XSLT 2.0转换中使用replace(., '^\s+|\s+$', '', 'm')
建议{{3 }}
相关代码部分是:
Source input = new StreamSource(new File("a.xml"));
TransformerFactory factory = TransformerFactory.newInstance();
Transformer wsTrimmer = factory.newTransformer(new StreamSource(new File("transform-trim-all.xslt")));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
wsTrimmer.transform(input, new StreamResult(bos));
JAXBElement<?> oUnmarshalled = (JAXBElement<?>) unmarshaller.unmarshal(new ByteArrayInputStream(bos.toByteArray()));
代码在运行时路径上需要Saxon HE,因为使用的是XSLT,我使用了以下常春藤依赖项:
<dependency org="net.sf.saxon" name="Saxon-HE" rev="9.4"/>
XSLT 是:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:sequence select="replace(., '^\s+|\s+$', '', 'm')"/>
</xsl:template>
</xsl:stylesheet>