JAXB @XmlRootElement with the same name



我有一个很长的XML,如下所示:

<Author>
<id></id>
<name></name>
<title></title>
<address></address>
....
</Author>

我以前使用 JAXB 来解析 XML。

JAXBContext.newInstance(Author.class);

我的作者呢.java

@XmlRootElement(name = "Author")
public class Author {
private String id;
private String name;
private String title;
private String address;
...
}

它运行良好,但我不想每次都将整个XML解析为一个大的Javabean。

所以,我想使用以下方式:

创建评论员.java

@XmlRootElement(name = "Author")
public class Commentator {
private String id;
private String name;
// setters, getters
}

创建分析师.java

@XmlRootElement(name = "Author")
public class Analyst {
private String title;
private String address;
// setters, getters
}

我写下面的代码来测试。

JAXBContext context = JAXBContext.newInstance(Analyst.class, Commentator.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
String xml = "<Author> <id>1</id> <name>A</name> <title>B</title> <address>C</address></Author>";
Commentator obj = (Commentator) unmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
System.out.println(obj);

它将打印正确的分辨率。

如果我想得到分析师。

Analyst a = (Analyst) unmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));

我会得到例外:java.lang.ClassCastException: com.xxx.Commentator cannot be cast to com.xxx.Analyst

我不确定这种方式对解析器是否正确。但我真的需要这样的功能。

在我看来,映射多个Java类是一个有点笨拙的设计 具有相同的@XmlRootElement. 但是,尽管如此,您仍然能够实现您想要的。

您需要不同的JAXBContextAnalystCommentator
而且因为JAXBContext是一个大对象,JAXBContext.newInstance(...)需要相当长的时间才能执行, 将这些JAXBContext实例保存在static变量中是有意义的 并重用这些而不是创建新的:

private static JAXBContext analystContext;
private static JAXBContext commentatorContext;

if (analystContext == null)
analystContext = JAXBContext.newInstance(Analyst.class);
if (commentatorContext == null)
commentatorContext = JAXBContext.newInstance(Commentator.class);

因此,您还需要从它们创建不同的Unmarshaller

Unmarshaller analystUnmarshaller = analystContext.createUnmarshaller();
Unmarshaller commentatorUnmarshaller = commentatorContext.createUnmarshaller();

然后,您可以将相同的 XML 内容取消封送到不同的根类:

String xml = "<Author> <id>1</id> <name>A</name> <title>B</title> <address>C</address></Author>";
Analyst analyst = (Analyst) analystUnmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
Commentator commentator = (Commentator) commentatorUnmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));

只需找到一种快速的方法即可:

  1. 注册 pojo。

JAXBContext context = JAXBContext.newInstance(Analyst.class, Commentator.class);

  1. 处理输入。我正在将str-xml转换为StreamSource。
String xml = "<Author> <id>1</id> <name>A</name> <title>B</title> <address>C</address></Author>";
StreamSource source = new StreamSource(new ByteArrayInputStream(xml.getBytes()));
  1. 创建解组器。

Unmarshaller unmarshaller = context.createUnmarshaller();

  1. (important( 取消封送数据时,请给出第二个参数(要解组哪个类(

JAXBElement<Analyst> unmarshal = unmarshaller.unmarshal(source, Analyst.class);

然后,得到你想要的:

Analyst analyst = unmarshal.getValue();

  1. 如果需要另一个pojo。请注意,unmarshaller&source不能在方法中重用(

JAXBElement<Commentator> unmarshal2 = unmarshaller2.unmarshal(source2, Commentator.class);

然后:

Commentator com = unmarshal2.getValue();

没有错误报告和结果是正确的。

相关内容

最新更新