简体   繁体   English

在保持顺序的同时将元素解组到列表中

[英]Unmarshalling elements into list while maintaining the order

I have an XML structure that I want to unmarshal using JaxB, while maintaining the order:我有一个 XML 结构,我想使用 JaxB 对其进行解组,同时保持顺序:

<body>
    <apple>
        <!-- ... -->
    </apple>
    <banana>
        <!-- ... -->
    </banana>
    <apple>
        <!-- ... -->
    </apple>
</body>

With this snippet I get the desired output有了这个片段,我得到了想要的输出

@XmlElement(name = "apple")
List<Apple> apples;
@XmlElement(name = "banana")
List<Banana> bananas;

// getters & setter

I get the desired output, but in the "wrong" order.我得到了所需的输出,但顺序“错误”。 So if I iterate the lists, I would get所以如果我迭代列表,我会得到

1. Apple
2. Apple
3. Banana

In the XML above, the order was:在上面的 XML 中,顺序是:

1. Apple
2. Banana
3. Apple

My idea was to make an abstract class (or interface) Fruit, so that Apple and Banana can extend from it:我的想法是创建一个抽象类(或接口) Fruit,以便 Apple 和 Banana 可以从中扩展:

abstract class Fruit{}

class Apple extends Fruit{
    //...
}
class Banana extends Fruit{
    //...
}

Then unmarshal the elements Apple and Banana into a (Linked-)List of Fruit s, as shown here :然后将 Apple 和 Banana 元素解组为Fruit的 (Linked-)List,如下所示

List<Fruit> fruits;

@XmlElements({
    @XmlElement(name = "apple", type = Apple.class),
    @XmlElement(name = "banana", type = Banana.class)
})

@XmlElementWrapper
public List<Fruit> getFruits() {
    return fruits;
}

Unfortunately, fruits stays null .不幸的是, fruits仍然是null

It worked for me without @XmlElementWrapper annotation:它在没有@XmlElementWrapper注释的情况下对我@XmlElementWrapper

@XmlElements({
    @XmlElement(name = "apple", type = Apple.class),
    @XmlElement(name = "banana", type = Banana.class)
})
public List<Fruit> getFruits() {
    return fruits;
}

I suppose @XmlElementWrapper expects one more element fruits inside the body element.我想@XmlElementWrapper期望在body元素中再增加一个元素fruits

Update (full code):更新(完整代码):

public class Main {

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

        JAXBContext ctx = JAXBContext.newInstance(Body.class);
        Body b = (Body)ctx.createUnmarshaller().unmarshal(new StreamSource(new StringReader(xml)));
        System.out.println(b.getFruits());
    }

    static String xml = "<body>\n"
            + "    <apple>\n"
            + "        <!-- ... -->\n"
            + "    </apple>\n"
            + "    <banana>\n"
            + "        <!-- ... -->\n"
            + "    </banana>\n"
            + "    <apple>\n"
            + "        <!-- ... -->\n"
            + "    </apple>\n"
            + "</body>";
}

@XmlRootElement(name = "body")
public class Body {

    private List<Fruit> fruits;

    @XmlElements({
        @XmlElement(name = "apple", type = Apple.class),
        @XmlElement(name = "banana", type = Banana.class)
    })
    public List<Fruit> getFruits() {
        return fruits;
    }

    public void setFruits(List<Fruit> fruits) {
        this.fruits = fruits;
    }

}

public abstract class Fruit {
    
}

public class Apple extends Fruit {
    
}

public class Banana extends Fruit {
    
}

Output of main() method: main()方法的输出:

[org.kdv.so.models.Apple@530612ba, org.kdv.so.models.Banana@2a40cd94, org.kdv.so.models.Apple@f4168b8]

Dependencies:依赖项:

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.1</version>
    <type>jar</type>
</dependency>
<dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.1</version>
</dependency>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM