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

从JAXB泛型中删除xsi:type,xmlns:xs和xmlns:xsi

王翰墨
2023-03-14
问题内容

使用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)
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;
    }
}

输出:

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

问题答案:

通用测试

您的JAXB(JSR-222)实现将为每个类创建映射(即TestGeneric,不是type(即TestGeneric<Integer>)。因此,它将value字段视为type
Object。这将导致xsi:type属性,因为JAXB实现正在添加足够的信息才能解组相同的类型。

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

    public TestGeneric() {
    }

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

演示版

下面是您可以使用的一种方法。我介绍了的子类TestGeneric来代表不同的可能类型。

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时,我希望在使用泛型时从XML元素中删除多余的名称空间/类型。我该怎么做,或者我做错了什么?我想使用泛型,这样我只需要编写一次代码块。 示例代码: 输出:

  • 在代码中创建了这些类的实例之后,我调用了传递所需值的setter方法。尽管该方法的参数是Object,但其值最有可能是字符串(我无法控制它是如何定义的)。但是,为了保持一致,我将字符串转换为Object,以便它与方法的参数类型匹配。代码如下所示: 当我对Java对象进行整理时,我会在结果XML中得到以下内容,就在字符串值的前面: 我读过关于方法的参数类型和传递给它的数据类型不匹配的文章。在我的例子

  • 问题内容: 我使用JAXB创建文件夹和文件层次结构 我的模特: 我想制作目录和文件树: 但是我在生成的xml中有一个奇怪的“ xsi:type”和“ xmlns:xsi”: 所以我的问题是:这是什么意思,如何删除? 问题答案: 在您的类中,您没有指定集合的​​类型,这就是JAXB添加属性的原因。 你有: 如果您要包含的实例,则可以执行以下操作: 如果由于某种原因您不想在集合中指定类型,则可以在批注

  • 但是我在生成的XML中有奇怪的“xsi:type”和“xmlns:xsi”: 所以我的问题是:这是什么意思,如何删除它?

  • 问题内容: 我正在尝试使用JAXB的自省功能来编组和分解所有使用JAXB批注标记的现有域对象。大多数事情都按预期运行,但是要获得一个相当简单的类进行序列化,我会遇到很多麻烦。此类在许多bean上用作@XmlElement,看起来像: 我尝试执行以下操作,但没有成功,JAXB仍然对接口Comparable感到愤怒。 将Range和DoubleRange都用作bean getter的返回类型会产生如下

  • 我正在尝试使用JAXB从遗留系统中解压XML文档。我的xml结构如下所示: