JAXB/Jackson:没有父标签的两个元素的序列

2024-04-27

Update: 寻找杰克逊orJAXB 解决方案。

在对 Jackson 的行为进行了一些研究之后,我发现 Jackson 总是会使用集合的包装器。所以杰克逊可能无法满足我的需求。因此,将 JAXB 添加到标题中。


原始问题

我需要为以下 XML 模式创建 POJO。

<ABWrap>
    <A></A>
    <B></B>
    <A></A>
    <B></B>
    ...
    ... n times
</ABWrap>

我尝试过跟踪 POJO。但这些并没有产生预期的结果。

class AB {
    @JacksonXmlProperty(localName = "A")
    private String A;
    @JacksonXmlProperty(localName = "B")
    private String B;
}

@JacksonXmlRootElement(localName = "ABWrap")
class ABWrap {
    @JacksonXmlElementWrapper(useWrapping = false)
    private AB[] ab = new AB[n];
}

我需要维持那双的状态<A></A> and <B></B>应该走到一起。元素的顺序很重要。
以下模式不适用于我的情况:

<ABWrap>
    <A></A>
    <A></A>
    ...
    ... n times
    <B></B>
    <B></B>
    ...
    ... n times
</ABWrap>

我已经能够实现第二个了。但我一直无法找到生成第一个模式的方法。


更新@mart的答案:

我定义了ABWrap, ABInterface and A如下:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ABWrap")
public class ABWrap {
    @XmlElements({@XmlElement(name = "A", type = A.class), @XmlElement(name = "B", type = B.class)})
    private List<ABInterface> ab;
}

public interface ABInterface { }

public class A implements ABInterface {
    @XmlValue
    private String a;
}

B定义类似于A.

主要方法如下:

public class Application {

    public static void main(final String[] args) throws JAXBException {

        JAXBContext jaxbContext = JAXBContext.newInstance(ABWrap.class);
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        A a = new A("a");
        B b = new B("b");
        ABWrap abWrap = new ABWrap(Arrays.asList(a, b));
        marshaller.marshal(abWrap, System.out);
    }
}

但此解决方案失败并出现以下错误:(jaxbpoc是项目名称)

If a class has @XmlElement property, it cannot have @XmlValue property.
this problem is related to the following location:
    at private java.lang.String ...jaxbpoc.A.a
    at ...jaxbpoc.A
    at private java.util.List ...jaxbpoc.ABWrap.ab
    at ...jaxbpoc.ABWrap
this problem is related to the following location:
    at public java.lang.String ...A.getA()
    at ...jaxbpoc.A
    at private java.util.List ...jaxbpoc.ABWrap.ab
    at ...jaxbpoc.ABWrap
If a class has @XmlElement property, it cannot have @XmlValue property.
this problem is related to the following location:
    at private java.lang.String ...jaxbpoc.B.b
    at ...jaxbpoc.B
    at private java.util.List ...jaxbpoc.ABWrap.ab
    at ...jaxbpoc.ABWrap
    ....
    ....
Class has two properties of the same name "a"
this problem is related to the following location:
    at public java.lang.String ...jaxbpoc.A.getA()
    at ...jaxbpoc.A
    at private java.util.List ...jaxbpoc.ABWrap.ab
    at ...jaxbpoc.ABWrap
this problem is related to the following location:
    ....
    ....

你可以这样做:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ABWrap")
public class ABWrap {
    @XmlElements({
            @XmlElement(name="A", type = A.class),
            @XmlElement(name="B", type = B.class),
    })
    private List<Letter> letters;
}

A、B 看起来像这样:

public class A implements Letter {
    @XmlValue
    private String a;
}

A、B 的通用接口没有做太多事情:

public interface Letter { }

Update:

正如我在评论中提到的,我尝试将 XML 转换为 POJO,反之亦然,并且它有效。我在这里粘贴了我用来测试的简单程序,所以请让我知道它如何为您工作,以便我可以进一步探索。

XmlToPojo:

public static void main(String[] args) {
        try {
            File file = new File("AB.xml");
            JAXBContext jaxbContext = JAXBContext.newInstance(ABWrap.class);

            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

            ABWrap pojo = (ABWrap) jaxbUnmarshaller.unmarshal(file);
        } catch (JAXBException e) {
            e.printStackTrace();
        }

    }

以及 POJO 到 xml:

public static void main(String[] args) {
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(ABWrap.class);
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            A a = new A("testA");
            B b = new B("testB");
            ABWrap abWrap = new ABWrap(Arrays.asList(a, b));
            marshaller.marshal(abWrap, System.out);

        } catch (JAXBException e) {
            e.printStackTrace();
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAXB/Jackson:没有父标签的两个元素的序列 的相关文章

随机推荐