gpt4 book ai didi

java - 用于任意 XML 的 JAXB @XmlAdapter

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

我有一个 org.w3c.dom.Element,我从我的 XmlAdapter 返回一个自定义 @XmlElement 并且我'我想将它作为任意 XML 的 JAXB 对象的一部分包含在内(我知道我必须手工制作 XSD)。但是,JAXB 提示

org.w3c.dom.Element is an interface, and JAXB can't handle interfaces.

显然 w3c XML 类型是 not supported as Java types ,这是一种耻辱。但除此之外,当我使用显然受支持的 javax.xml.transform.Result 时,我遇到了同样的错误。

如何在 JAXB 中包含任意 XML 元素作为元素?

注意:根据 https://forums.oracle.com/thread/1668210我也试过了

MessageFactory factory = MessageFactory.newInstance();
message = factory.createMessage();
SOAPElement element = message.getSOAPBody().addDocument(doc);

但这也给出了同样的错误。

最佳答案

长话短说

只要将值类型指定为 ,您就可以拥有一个将域对象转换为 org.w3c.dom.Element 实例的 XmlAdapter对象(不是元素)。


下面是一个完整的例子。

Xml 适配器

java.lang.Object 类型的字段/属性会将未知内容保留为 DOM 节点。您可以在您的用例中通过将 XmlAdapter 中的值类型指定为 Object 来利用这一点。您需要确保从 marshal 方法返回的根元素与 @XmlElement 注释定义的字段/属性相匹配。

import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.*;
import org.w3c.dom.*;

public class BarAdapter extends XmlAdapter<Object, Bar>{

private DocumentBuilder documentBuilder;

public BarAdapter() {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
documentBuilder = dbf.newDocumentBuilder();
} catch(Exception e) {
// TODO - Handle Exception
}
}

@Override
public Bar unmarshal(Object v) throws Exception {
Bar bar = new Bar();
Element element = (Element) v;
bar.value = element.getTextContent();
return bar;
}

@Override
public Object marshal(Bar v) throws Exception {
Document document = documentBuilder.newDocument();
Element root = document.createElement("bar");
root.setTextContent(v.value);
return root;
}

}

Java 模型

@XmlJavaTypeAdapter 注释用于引用 XmlAdapter

import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

@XmlJavaTypeAdapter(BarAdapter.class)
private Bar bar;

}

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Bar {

String value;

}

演示代码

演示

由于创建 DocumentBuilderFactory 是有成本的,我们可以通过在 Marshaller 上设置一个实例来利用 JAXB 的能力来处理 XmlAdapter 的有状态实例。

import java.io.File;
import javax.xml.bind.*;

public class Demo {

public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Foo.class);

Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum18272059/input.xml");
Foo foo = (Foo) unmarshaller.unmarshal(xml);

Marshaller marshaller = jc.createMarshaller();
marshaller.setAdapter(new BarAdapter());
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(foo, System.out);
}

}

input.xml/输出

<?xml version="1.0" encoding="UTF-8"?>
<foo>
<bar>Hello World</bar>
</foo>

关于java - 用于任意 XML 的 JAXB @XmlAdapter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18272059/

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