当前位置: 首页 > 面试题库 >

JAXB @XmlAdapter用于任意XML

云瑞
2023-03-14
问题内容

我有一个自定义org.w3c.dom.Element返回的我想将它作为任意XML包含在JAXB对象中(我知道我必须手工制作XSD)。但是,JAXB抱怨XmlAdapter``@XmlElement

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

显然,不支持将w3c
XML类型作为Java类型来支持,这很遗憾。但是,除此之外,使用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);

但这也给了同样的错误。


问题答案:

TL; DR

只要您将值类型指定为(not
XmlAdapter,就可以将域对象转换为的实例。org.w3c.dom.Element``Object``Element

下面是一个完整的示例。

XmlAdapter

类型的字段/属性java.lang.Object会将未知内容保留为DOM节点。您可以在用例中通过在XmlAdapteras中指定值类型来利用它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模型

oo

@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>


 类似资料:
  • 我正在使用JAXB XMLadapter封送和反封送布尔值。应用程序的XML文件也将被C#应用程序访问。我们必须验证这个XML文件,这是使用XSD完成的。C#应用程序为布尔节点编写“true”值。但XSD也验证了这一点,因为它只允许“true/false”或“1/0”。因此,我们在XSD中保留了布尔值的String,该String将由XMLAdapter验证,以便在我们这边进行封送和反封送。XML

  • 问题内容: 我正在使用JAXB XMLadapter来编组和解组布尔值。C#应用程序也将访问该应用程序的XML文件。我们必须验证此XML文件,这是使用XSD完成的。C#应用程序为布尔节点写入“ True”值。但是我们的XSD确实验证了同样的结果,因为它只允许“ true / false”或“ 1/0”。因此,我们在XSD中将String保留为布尔值,并且XMLAdapter会验证该字符串是否在我们

  • 即使在尝试了许多事情之后也无法找到解决方案,因此在此处发布希望获得一些解决此问题或修复方法。 基本上,如果 ,但是除了< code>Map之外,我还需要一个< code>@XmlElement。因此有一个字段用< code >(映射字段)@XmlPath(" .)和另一个带有< code>@XmlElement的字符串字段,然后我想执行< code >解组。 以下是我尝试 : 下面是它将被< co

  • 有了这个Jaxb Xml定义,我尝试通过添加来移除映射元素包装器,但在解压缩过程中会导致异常 EventAdapter是 我的输出是 我尝试通过添加来删除标记 产量不错 但撤退失败了 调试Jaxb使我熟悉了这一行

  • 我将以这种方式比较两本词典: 但我有个错误 二进制运算符“==”不能应用于两个“[任意哈希表:任意]!”操作数 如何解决这个问题?请帮帮我谢谢

  • 背景: 我使用JAXB将XML解组为Java对象。最初,我只是使用JAXB来执行解组。然后对代码进行静态分析,并提出了XML外部实体注入的高关键性问题。经过一点研究,我发现了一个建议(https://www.owasp.org/index.php/XML_External_Entity_(XXE)_Prevention_Cheat_Sheet#JAXB_Unmarshaller)使用配置为防止解析