Need help in formatting JAXB output

2019-02-19 05:09发布

I have some objects let's say two, A and B. These objects from the same class. I need to marshal these objects using JAXB and the output XML should be in this form:

<Root>
    <A>
        <ID> an id </ID>
    </A>
    <B>
        <ID> an id </ID>
    </B>
</Root>

<!-- Then all A and B attributes must be listed !-->
<A>
    <ID> an id </ID>
    <attribute1> value </attribute1>
    <attribute2> value </attribute2>
</A>
<B>
    <ID> an id </ID>
    <attribute1> value </attribute1>
    <attribute2> value </attribute2>
</B>

How to generate this format in JAXB? Any help is appreciated.

Update: To be more specific, Assume we have Human class like this:

@XmlRootElement
public class Human {
    private String name;
    private int age;
    private Integer nationalID;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Integer getNationalID() {
        return nationalID;
    }

    public void setNationalID(Integer nationalID) {
        this.nationalID = nationalID;
    }
}

and our main class is:

public class Main3 {

    public static void main(String[] args) throws JAXBException {
        Human human1 = new Human();
        human1.setName("John");
        human1.setAge(24);
        human1.setNationalID(Integer.valueOf(123456789));

        JAXBContext context = JAXBContext.newInstance(Human.class);
        Marshaller m = context.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

        StringWriter stringWriter = new StringWriter();

        m.marshal(human1, stringWriter);

        System.out.println(stringWriter.toString());
    }

}

Then the output will be:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<human>
    <age>24</age>
    <name>John</name>
    <nationalID>123456789</nationalID>
</human>

Now I need the output to be like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<human>
    <nationalID>123456789</nationalID>
</human>
<human>
    <nationalID>123456789</nationalID>
    <age>24</age>
    <name>John</name>
</human>

And this will help me draw a tree of XML objects without the attributes (only by ID) and then but all the definitions below the tree. Is this possible using JAXB or any other implementation?

2条回答
姐就是有狂的资本
2楼-- · 2019-02-19 05:29
package com.namasoft.dms.gui.common.utilities;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessorOrder;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlID;
import javax.xml.bind.annotation.XmlIDREF;
import javax.xml.bind.annotation.XmlRootElement;

public class JAXB
{

    public static class Human
    {

        @XmlID
        String id;
        @XmlElement
        String name;
        @XmlElement
        int age;

        public Human()
        {
        }

        public Human(String name)
        {
            this.id = this.name = name;
            age = new Random().nextInt();
        }
    }

    @XmlRootElement
    public static class HumansList
    {
        @XmlElementWrapper(name = "humanObjects")
        @XmlElement(name = "human")
        List<Human> humanObjects = new ArrayList<>();

        @XmlIDREF
        @XmlElementWrapper(name = "humanIds")
        @XmlElement(name = "id")
        List<Human> humanIds = new ArrayList<>();

        void addHuman(Human human)
        {
            humanObjects.add(human);
            humanIds.add(human);
        }
    }

    public static void main(String[] args) throws JAXBException
    {
        HumansList list = new HumansList();
        Human parent1 = new Human("parent1");
        list.addHuman(parent1);
        Human child11 = new Human("child11");
        list.addHuman(child11);
        Human child12 = new Human("child12");
        list.addHuman(child12);

        Human parent2 = new Human("parent2");
        list.addHuman(parent2);
        Human child21 = new Human("child21");
        list.addHuman(child21);
        Human child22 = new Human("child22");
        list.addHuman(child22);

        JAXBContext context = JAXBContext.newInstance(HumansList.class);
        Marshaller m = context.createMarshaller();
        StringWriter xml = new StringWriter();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        m.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");

        m.marshal(list, xml);
        System.out.println(xml);
    }
}

The output will be

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<humansList>
    <humanObjects>
        <human>
            <id>parent1</id>
            <name>parent1</name>
            <age>-486071665</age>
        </human>
        <human>
            <id>child11</id>
            <name>child11</name>
            <age>920318383</age>
        </human>
        <human>
            <id>child12</id>
            <name>child12</name>
            <age>-1355111983</age>
        </human>
        <human>
            <id>parent2</id>
            <name>parent2</name>
            <age>-314154051</age>
        </human>
        <human>
            <id>child21</id>
            <name>child21</name>
            <age>983544381</age>
        </human>
        <human>
            <id>child22</id>
            <name>child22</name>
            <age>748252616</age>
        </human>
    </humanObjects>
    <humanIds>
        <id>parent1</id>
        <id>child11</id>
        <id>child12</id>
        <id>parent2</id>
        <id>child21</id>
        <id>child22</id>
    </humanIds>
</humansList>
查看更多
Emotional °昔
3楼-- · 2019-02-19 05:44

Try this:

import java.io.StringWriter;
import javax.xml.bind.Marshaller;

...

Object requestObject = ...  // This is the object that needs to be printed with indentation
Marshaller marshaller = ...
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter stringWriter = new StringWriter();
marshaller.marshal(requestObject, stringWriter);

System.out.println(stringWriter.toString());
查看更多
登录 后发表回答