本文介绍了从JAXB Generics中删除xsi:type,xmlns:xs和xmlns:xsi的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用JAXB时,我想在使用泛型时从我的XML元素中删除多余的名称空间/类型。我该怎么做,或者我做错了什么?我希望使用泛型,这样我只需编写一段代码即可。



示例代码:

  public static void main(String [] args){
try {
TestRoot root = new TestRoot();
root.name.value =bobby;
root.age.value = 102;
root.color.value =blue;

JAXBContext context = JAXBContext.newInstance(root.getClass());
Marshaller marsh = context.createMarshaller();
marsh.setProperty(Marshaller.JAXB_ENCODING,UTF-8);
marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE);

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
marsh.marshal(root,pw);
System.out.println(sw.toString());
}
catch(Throwable t){
t.printStackTrace();



@XmlRootElement
static class TestRoot {
@XmlElement public TestGeneric< String> name = new TestGeneric< String>(true);
@XmlElement public TestGeneric< Integer> age = new TestGeneric< Integer>(true);
@XmlElement public TestWhatIWouldLike color = new TestWhatIWouldLike(true);
}

@XmlAccessorType(XmlAccessType.NONE)
静态类TestGeneric< T> {
@XmlAttribute public boolean isRequired;
@XmlElement公共T值;
$ b $ public TestGeneric(){
}

public TestGeneric(boolean isRequired){
this.isRequired = isRequired;


$ b @XmlAccessorType(XmlAccessType.NONE)
静态类TestWhatIWouldLike {
@XmlAttribute public boolean isRequired;
@XmlElement public String value;
$ b $ public TestWhatIWouldLike(){
}

public TestWhatIWouldLike(boolean isRequired){
this.isRequired = isRequired;


$ / code $ / pre
$ b $输出:

 <?xml version =1.0encoding =UTF-8standalone =yes?> 
< testRoot>
< name isRequired =true>
<值xsi:type =xs:stringxmlns:xs =http://www.w3.org/2001/XMLSchemaxmlns:xsi =http://www.w3.org/ 2001 / XMLSchema的实例>发夹< /值GT;
< / name>
< age isRequired =true>
<值xsi:type =xs:intxmlns:xs =http://www.w3.org/2001/XMLSchemaxmlns:xsi =http://www.w3.org/ 2001 / XMLSchema的实例> 102< /值GT;
< / age>
< color isRequired =true>
<值>蓝色< /值>
< / color>
< / testRoot>


解决方案

Test Generic ,而不是类型(即 TestGeneric< Integer> )。因此,它会将值字段视为类型 Object 这会导致 xsi:type 属性,因为您的JAXB实现正在添加足够的信息来解组相同的类型。

  @XmlAccessorType(XmlAccessType.NONE)
静态类TestGeneric< T> {
@XmlAttribute public boolean isRequired;
@XmlElement public T value;
$ b $ public TestGeneric(){
}
$ b $ public TestGeneric(boolean isRequired){
this.isRequired = isRequired;
}
}






演示

以下是您可以采用的方法我已经引入了 TestGeneric 的子类来表示不同的可能类型。

 包论坛11192623; 

import java.io.PrintWriter;
import java.io.StringWriter;

import javax.xml.bind。*;
import javax.xml.bind.annotation。*;

public class Demo {

public static void main(String [] args){
try {
TestRoot root = new TestRoot();
root.name.value =bobby;
root.age.value = 102;
root.color.value =blue;

JAXBContext context = JAXBContext.newInstance(root.getClass());
Marshaller marsh = context.createMarshaller();
marsh.setProperty(Marshaller.JAXB_ENCODING,UTF-8);
marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE);

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
marsh.marshal(root,pw);
System.out.println(sw.toString());
}
catch(Throwable t){
t.printStackTrace();



@XmlRootElement
static class TestRoot {
@XmlElement public TestString name = new TestString(true);
@XmlElement public TestInteger age = new TestInteger(true);
@XmlElement public TestString color = new TestString(true);

$ b @XmlAccessorType(XmlAccessType.NONE)
@XmlTransient
@XmlSeeAlso({TestInteger.class,TestString.class})
静态类TestGeneric< ; T> {
@XmlAttribute
public boolean isRequired;
公共T值;
$ b $ public TestGeneric(){
}

public TestGeneric(boolean isRequired){
this.isRequired = isRequired;
}
}

static class TestInteger extends TestGeneric< Integer> {
public TestInteger(){
}
public TestInteger(boolean b){
super(b);
}
@XmlElement
public Integer getValue(){
返回值;
}
public void setValue(Integer value){
this.value = value;
}
}

静态类TestString extends TestGeneric< String> {
public TestString(){
}
public TestString(boolean b){
super(b);
}
@XmlElement
public String getValue(){
返回值;
}
public void setValue(String value){
this.value = value;
}
}

}


When using JAXB, I'd like to remove the excess namespaces/types from my XML elements when using Generics. How can I do this or what am I doing wrong? I'd like to use Generics so that I only have to write a block of code once.

Example code:

public static void main(String[] args) {
    try {
        TestRoot root = new TestRoot();
        root.name.value = "bobby";
        root.age.value = 102;
        root.color.value = "blue";

        JAXBContext context = JAXBContext.newInstance(root.getClass());
        Marshaller marsh = context.createMarshaller();
        marsh.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");
        marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE);

        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        marsh.marshal(root,pw);
        System.out.println(sw.toString());
    }
    catch(Throwable t) {
        t.printStackTrace();
    }
}

@XmlRootElement
static class TestRoot {
    @XmlElement public TestGeneric<String> name = new TestGeneric<String>(true);
    @XmlElement public TestGeneric<Integer> age = new TestGeneric<Integer>(true);
    @XmlElement public TestWhatIWouldLike color = new TestWhatIWouldLike(true);
}

@XmlAccessorType(XmlAccessType.NONE)
static class TestGeneric<T> {
    @XmlAttribute public boolean isRequired;
    @XmlElement public T value;

    public TestGeneric() {
    }

    public TestGeneric(boolean isRequired) {
        this.isRequired = isRequired;
    }
}

@XmlAccessorType(XmlAccessType.NONE)
static class TestWhatIWouldLike {
    @XmlAttribute public boolean isRequired;
    @XmlElement public String value;

    public TestWhatIWouldLike() {
    }

    public TestWhatIWouldLike(boolean isRequired) {
        this.isRequired = isRequired;
    }
}

Output:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<testRoot>
    <name isRequired="true">
        <value xsi:type="xs:string" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">bobby</value>
    </name>
    <age isRequired="true">
        <value xsi:type="xs:int" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">102</value>
    </age>
    <color isRequired="true">
        <value>blue</value>
    </color>
</testRoot>
解决方案

Test Generic

Your JAXB (JSR-222) implementation is going to create mappings per class (i.e. TestGeneric, not type (i.e. TestGeneric<Integer>). As such it is going to treat the value field as type Object. This will result in the xsi:type attributes as your JAXB implementation is adding enough information to be able to unmarshal the same types.

@XmlAccessorType(XmlAccessType.NONE)
static class TestGeneric<T> {
    @XmlAttribute public boolean isRequired;
    @XmlElement public T value;

    public TestGeneric() {
    }

    public TestGeneric(boolean isRequired) {
        this.isRequired = isRequired;
    }
}


Demo

Below is an approach you could use. I have introduced subclasses of TestGeneric to represent the different possible types.

package forum11192623;

import java.io.PrintWriter;
import java.io.StringWriter;

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

public class Demo {

    public static void main(String[] args) {
        try {
            TestRoot root = new TestRoot();
            root.name.value = "bobby";
            root.age.value = 102;
            root.color.value = "blue";

            JAXBContext context = JAXBContext.newInstance(root.getClass());
            Marshaller marsh = context.createMarshaller();
            marsh.setProperty(Marshaller.JAXB_ENCODING,"UTF-8");
            marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE);

            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            marsh.marshal(root,pw);
            System.out.println(sw.toString());
        }
        catch(Throwable t) {
            t.printStackTrace();
        }
    }

    @XmlRootElement
    static class TestRoot {
        @XmlElement public TestString name = new TestString(true);
        @XmlElement public TestInteger age = new TestInteger(true);
        @XmlElement public TestString color = new TestString(true);
    }

    @XmlAccessorType(XmlAccessType.NONE)
    @XmlTransient
    @XmlSeeAlso({TestInteger.class, TestString.class})
    static class TestGeneric<T> {
        @XmlAttribute 
        public boolean isRequired;
        public T value;

        public TestGeneric() {
        }

        public TestGeneric(boolean isRequired) {
            this.isRequired = isRequired;
        }
    }

    static class TestInteger extends TestGeneric<Integer> {
        public TestInteger() {
        }
        public TestInteger(boolean b) {
            super(b);
        }
        @XmlElement
        public Integer getValue() {
            return value;
        }
        public void setValue(Integer value) {
            this.value = value;
        }
    }

    static class TestString extends TestGeneric<String> {
        public TestString() {
        }
        public TestString(boolean b) {
            super(b);
        }
        @XmlElement
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
    }

}

这篇关于从JAXB Generics中删除xsi:type,xmlns:xs和xmlns:xsi的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-23 16:53