我使用Jaxb2和Spring.我正在尝试解组由我的两个客户发送的一些XML.
到目前为止,我只需要处理一个发送了一些像这样的xml的客户:
<foo xmlns="com.acme">
<bar>[...]</bar>
<foo>
Run Code Online (Sandbox Code Playgroud)
绑定到这样的POJO:
@XmlType(name = "", propOrder = {"bar"})
@XmlRootElement(name = "Foo")
public class Foo {
@XmlElement(name = "Bar")
private String bar;
[...]
}
Run Code Online (Sandbox Code Playgroud)
我发现之前的开发人员在unmarshaller中硬编码了命名空间以使其工作.
现在,第二个客户发送相同的XML但更改名称空间!
<foo xmlns="com.xyz">
<bar>[...]</bar>
<foo>
Run Code Online (Sandbox Code Playgroud)
显然,unmarshaller没有解组,因为它期望一些{com.acme}foo而不是{com.xyz}foo.不幸的是,要求客户更改XML不是一种选择.
我尝试了什么:
1)在application-context.xml,我搜索了一个配置,它允许我忽略命名空间但找不到:
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="packagesToScan">
<list>
<value>com.mycompany.mypkg</value>
</list>
</property>
<property name="marshallerProperties">
<map>
<entry key="???"><value type="java.lang.Boolean">false</value></entry>
</map>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
似乎唯一可用的选项是Jaxb2Marshaller的Javadoc中列出的选项:
/**
* Set the JAXB {@code Marshaller} properties. These properties will be set on the
* underlying JAXB {@code Marshaller}, and allow for features such as indentation.
* @param properties the properties
* @see javax.xml.bind.Marshaller#setProperty(String, Object)
* @see javax.xml.bind.Marshaller#JAXB_ENCODING
* @see javax.xml.bind.Marshaller#JAXB_FORMATTED_OUTPUT
* @see javax.xml.bind.Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION
* @see javax.xml.bind.Marshaller#JAXB_SCHEMA_LOCATION
*/
public void setMarshallerProperties(Map<String, ?> properties) {
this.marshallerProperties = properties;
}
Run Code Online (Sandbox Code Playgroud)
2)我还尝试在代码中配置unmarshaller:
try {
jc = JAXBContext.newInstance("com.mycompany.mypkg");
Unmarshaller u = jc.createUnmarshaller();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false);//Tried this option.
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlFile.toFile());
u.unmarshal(new DOMSource(doc));
return (Foo)u.unmarshal(new StreamSource(xmlFile.toFile()));
} catch (ParserConfigurationException | SAXException | IOException | JAXBException e) {
LOGGER.error("Erreur Unmarshalling CPL");
}
Run Code Online (Sandbox Code Playgroud)
3)与SAXParser不同的形式:
try {
jc = JAXBContext.newInstance("com.mycompany.mypkg");
Unmarshaller um = jc.createUnmarshaller();
final SAXParserFactory sax = SAXParserFactory.newInstance();
sax.setNamespaceAware(false);
final XMLReader reader = sax.newSAXParser().getXMLReader();
final Source er = new SAXSource(reader, new InputSource(new FileReader(xmlFile.toFile())));
return (Foo)um.unmarshal(er);
}catch(...) {[...]}
Run Code Online (Sandbox Code Playgroud)
这一个有效!但是,我仍然希望能够自动装配Unmarshaller,而不必每次都需要这种丑陋的conf.
命名空间意识是文档读取器/构建器/解析器的功能,而不是编组器的功能。来自不同命名空间的 XML 元素代表不同的实体 == 对象,因此编组器不能忽略它们。
您正确地关闭了 SAX 阅读器中的名称空间,正如您所说,它有效。我不明白你的问题,你的编组器仍然可以被注入,不同之处在于获取输入数据。
文档生成器的相同技巧也应该有效(我稍后将对其进行测试),我怀疑您仍在使用具有“硬编码”名称空间的编组器,但您的文档是免费的名称空间。
在我的项目中我使用 XSLT 来解决类似的问题。设置命名空间感知绝对是更简单的解决方案。但是,使用 XSLT,我可以有选择地仅删除一些名称空间,而且我的输入 xml 并不总是相同(忽略名称空间),有时我必须重命名一些元素,因此 XSLT 为我提供了额外的灵活性。
要删除命名空间,您可以使用这样的 xslt 模板:
<xsl:stylesheet version="1.0" xmlns:e="http://timet.dom.robust.ed" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:template match="/">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()" />
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
<xsl:template match="text() | processing-instruction() | comment()">
<xsl:copy />
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
然后在 Java 中,在解组之前,我转换输入数据:
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
Source source = new DOMSource(xml);
DOMResult result = new DOMResult();
transformer.transform(source, result);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12037 次 |
| 最近记录: |