使用JAXB

时间:2015-11-09 08:19:00

标签: java xml jaxb

考虑两个同构的XML模式。通过这里的同构,我的意思是这两个模式除了属性和标签名称之外具有相同的结构。更具体地说,我有一个实例,一个是架构,比如说A,还有它的副本B,其中所有的标签和属性名称都是从英文翻译成国家的lamguage等价物。

例如,作为输入,我们可以有一个对象的两个不同变体:

<tag_1_v1>
    <tag_2_v1 id="blabla" name="xxxxx">
        Some value1
    </tag_2_v1>
    <tag_3_v1 id="alalala" name="yyyyy">
        Some value2
    </tag_3_v1>
</tag_1_v1>

<tag_1_v2>
    <tag_2_v2 special_id_2="blabla" name="xxxxx">
        Some value1
    </tag_2_v2>
    <tag_3_v2 id="alalala" special_name_2="yyyyy">
        Some value2
    </tag_3_v2>
</tag_1_v2>

问题是将这两个模式映射到单个类结构上,比如说

class Tag1 {
    Tag2 tag2;
    Tag3 tag3;
}

class Tag2 {
    String id;
    String name;
    String value;
}  

class Tag3 {
    String id;
    String name;
    String value;
} 

如何解决这个问题有各种各样的想法,但所有这些都不是那么方便,因为任何可能在同一类结构上使用单个JAXB注释方案。他们是:

  1. 创建两个不同的类集,然后从对象中复制值 一个模式到另一个;
  2. 创建自己的SAX解析器实现,并在其中“转换”标签和属性名称为适当的;
  3. 使用自己的XML预处理程序并使用字符串替换(如果在所有模式中id和属性名称不相同,则不起作用。)

1 个答案:

答案 0 :(得分:1)

由于每个<tag_i>可以具有不同的属性,因此一个干净的解决方案是使用继承:

  • 创建由Tag1Tag1V1继承的抽象类Tag1V2。将所有常用代码计入Tag1
  • 同样会Tag2Tag3

为了帮助您入门,这里将是Tag2的实现:

@XmlRootElement
@XmlSeeAlso({Tag2V1.class, Tag2V2.class})
abstract class Tag2 {

    private String name;
    private String content;

    @XmlAttribute(name = "name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlValue
    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}

@XmlRootElement(name = "tag_2_v1")
class Tag2V1 extends Tag2 {

    private String id;

    @XmlAttribute(name = "id")
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

}

@XmlRootElement(name = "tag_2_v2")
class Tag2V2 extends Tag2 {

    private String specialId2;

    @XmlAttribute(name = "special_id_2")
    public String getSpecialId2() {
        return specialId2;
    }

    public void setSpecialId2(String specialId2) {
        this.specialId2 = specialId2;
    }

}