Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/352.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JAXB将两个同构XML模式解析为一个类结构_Java_Xml_Jaxb - Fatal编程技术网

Java 使用JAXB将两个同构XML模式解析为一个类结构

Java 使用JAXB将两个同构XML模式解析为一个类结构,java,xml,jaxb,Java,Xml,Jaxb,考虑两种同构的XML模式。这里的同构意味着这两个模式除了属性和标记名之外,都有相同的结构。更具体地说,我有一个活生生的例子,比如was模式A,以及它的副本B,其中所有标记和属性名称都从英语翻译成了国家语言等价物 例如,作为输入,我们可以有一个对象的两个不同变体: <tag_1_v1> <tag_2_v1 id="blabla" name="xxxxx"> Some value1 </tag_2_v1> <tag_3

考虑两种同构的XML模式。这里的同构意味着这两个模式除了属性和标记名之外,都有相同的结构。更具体地说,我有一个活生生的例子,比如was模式
A
,以及它的副本
B
,其中所有标记和属性名称都从英语翻译成了国家语言等价物

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

<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>
对于如何解决这个问题,有各种各样的想法,但它们都不是那么方便,因为在同一类结构上使用单个JAXB注释方案是不可能的。它们是:

  • 创建两个不同的类集,然后从 将一种模式转换为另一种模式
  • 创建自己的SAX解析器实现,并将其内部的标记和属性名称“翻译”为适当的名称
  • 使用自己的XML预处理器并使用字符串替换(如果所有模式中的id和属性名称不相同,则将不起作用)
  • 由于每个
    都可以有不同的属性,因此一个干净的解决方案是使用继承:

    • 创建由
      Tag1V1
      Tag1V2
      继承的抽象类
      Tag1
      。将所有常用代码分解为
      Tag1
    • 同样的情况也会发生在
      Tag2
      Tag3
    为了让您开始,下面是
    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;
        }
    
    }
    

    我可能会选择选项2。这听起来像是最简单的选择。
    class Tag1 {
        Tag2 tag2;
        Tag3 tag3;
    }
    
    class Tag2 {
        String id;
        String name;
        String value;
    }  
    
    class Tag3 {
        String id;
        String name;
        String value;
    } 
    
    @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;
        }
    
    }