gpt4 book ai didi

java - JAXB 和无命名空间的 XML

转载 作者:数据小太阳 更新时间:2023-10-29 01:58:25 26 4
gpt4 key购买 nike

供应商提供的 XML 如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Foo>
<Bar>...</Bar>
<Bar>...</Bar>
</Foo>

请注意,没有 xmlns="..." 声明,供应商也不提供架构。这是无法更改的,供应商将来会继续以这种方式提供 XML。

为了生成 JAXB 绑定(bind),我创建了一个如下模式:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://acme.com/schema"
xmlns:tns="http://acme.com/schema"
elementFormDefault="qualified">
<xsd:element name="Foo">
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="tns:Bar" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="Bar">
...
</xsd:element>
</xsd:schema>

请注意,我已经声明了一个或多或少有意义的 namespace (“http://acme.com/schema”),以便它可以用于元素引用等。XJC 生成以下 package-info.java :

@javax.xml.bind.annotation.XmlSchema(namespace = "http://acme.com/schema", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.acme.schema;

然后我尝试解码 XML 文档:

JAXBContext jaxb = JAXBContext.newInstance("com.acme.schema");
Unmarshaller unmarshaller = jaxb.createUnmarshaller();
InputStream is = this.getClass().getClassLoader().getResourceAsStream("test.xml");

InputSource source = new InputSource(is);
Foo foo = (Foo) unmarshaller.unmarshal(source);

这是我得到的异常:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Foo"). Expected elements are <{http://acme.com/schema}Foo>,...>

显然,发生这种情况是因为 XML 元素属于空命名空间,而 JAXB 类具有非空命名空间。

有没有办法伪造一个 XML 命名空间(可能在 XML 解析期间),以便 JAXB 识别元素并成功绑定(bind)它们? SAX/StAX 解决方案优于 DOM,因为 XML 文档可能相当庞大。

最佳答案

首先,我不推荐所有这些。与第三方 API 集成已经足够复杂,无需增加额外的复杂性。为什么要费心添加命名空间呢?我不确定你从中得到了什么。想想能够继承您的代码库的幸运者。他们会看到命名空间的添加,但不知道您为什么要这样做。

我什至会更进一步,建议完全避免模式,而只使用带注释的 POJO。所有这些步骤只会增加复杂性、构建步骤等。

但是,如果您下定决心,这似乎是 XSL 转换的典型案例。您可以找到一个非常容易添加 namespace 的 XSL 转换,例如 this question然后将您的转换连接到 JAXB 中是一件简单的事情...

private static Foo unmarshalDocument(InputStream xslStream, InputStream xmlStream) throws Exception {
StreamSource stylesource = new StreamSource(xslStream);
StreamSource inputStream = new StreamSource(xmlStream);
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
JAXBResult result = new JAXBResult(context);
transformer.transform(inputStream, result);
return (Foo) result.getResult();
}

关于java - JAXB 和无命名空间的 XML,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37402341/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com