Как мне разобрать этот XML в Java с JAXB? - PullRequest
36 голосов
/ 18 ноября 2011

У меня есть следующий XML, без XSD или схемы с ним, который я хочу проанализировать для объекта (ов) java, используя JAXB, поскольку я слышал, что он лучше, чем SAX.Есть ли способ сделать это с помощью аннотаций или лучший способ сделать это?Делает ли это так, что мне просто нужен один класс FosterHome?У меня проблемы с поиском, как сделать это, любая помощь благодарна.

Я изначально думал о том, чтобы иметь класс FosterHome, Family и Child.Используя JAXB, больше не нужно иметь 3 класса?Я не уверен, как с этим справиться, так как ChildID обнаруживается в двух разных областях.

<?xml version="1.0" encoding="UTF-8"?>
<FosterHome>
    <Orphanage>Happy Days Daycare</Orphanage>
    <Location>Apple Street</Location>
    <Families>
        <Family>
            <ParentID>Adams</ParentID>
            <ChildList>
                <ChildID>Child1</ChildID>
                <ChildID>Child2</ChildID>
            </ChildList>
        </Family>
        <Family>
            <ParentID>Adams</ParentID>
            <ChildList>
                <ChildID>Child3</ChildID>
                <ChildID>Child4</ChildID>
            </ChildList>
        </Family>
    </Families>
    <RemainingChildList>
        <ChildID>Child5</ChildID>
        <ChildID>Child6</ChildID>
    </RemainingChildList>
</FosterHome>

Ответы [ 3 ]

60 голосов
/ 18 ноября 2011

Вы можете сделать следующее.Используя @XmlElementWrapper, вы можете уменьшить количество классов, которые вам нужны:

FosterHome

package nov18;

import java.util.List;
import javax.xml.bind.annotation.*;

@XmlRootElement(name="FosterHome")
@XmlAccessorType(XmlAccessType.FIELD)
public class FosterHome {

    @XmlElement(name="Orphanage")
    private String orphanage;

    @XmlElement(name="Location")
    private String location;

    @XmlElementWrapper(name="Families")
    @XmlElement(name="Family")
    private List<Family> families;

    @XmlElementWrapper(name="RemainingChildList")
    @XmlElement(name="ChildID")
    private List<String> remainingChildren;

}

Family

package nov18;

import java.util.List;   
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
public class Family {

    @XmlElement(name="ParentID")
    private String parentID;

    @XmlElementWrapper(name="ChildList")
    @XmlElement(name="ChildID")
    private List<String> childList;

}

Демо

package nov18;

import java.io.File;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(FosterHome.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        FosterHome fosterHome = (FosterHome) unmarshaller.unmarshal(new File("src/nov18/input.xml"));

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(fosterHome, System.out);
    }

}

Вход / Выход

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FosterHome>
    <Orphanage>Happy Days Daycare</Orphanage>
    <Location>Apple Street</Location>
    <Families>
        <Family>
            <ParentID>Adams</ParentID>
            <ChildList>
                <ChildID>Child1</ChildID>
                <ChildID>Child2</ChildID>
            </ChildList>
        </Family>
        <Family>
            <ParentID>Adams</ParentID>
            <ChildList>
                <ChildID>Child3</ChildID>
                <ChildID>Child4</ChildID>
            </ChildList>
        </Family>
    </Families>
    <RemainingChildList>
        <ChildID>Child5</ChildID>
        <ChildID>Child6</ChildID>
    </RemainingChildList>
</FosterHome>

Для получения дополнительной информации

ОБНОВЛЕНИЕ

Есть ли простой способ, которым я могу перебрать / распечатать все ChildID в классе Family?

Вы могли бы сделатьследующее:

    for(Family family : fosterHome.getFamilies()) {
        System.out.println(family.getParentID());
        for(String childID : family.getChildList()) {
            System.out.println("    " + childID);
        }
    }
3 голосов
/ 18 ноября 2011
try {
    // create a JAXBContext capable of handling classes generated into
    // the com.abhi.xml.jaxb.generated package
    JAXBContext jc = JAXBContext.newInstance( "com.abhi.xml.jaxb.generated" );

    // create an Unmarshaller
    Unmarshaller u = jc.createUnmarshaller();

    // unmarshal a FosterHome instance document into a tree of Java content
    // objects composed of classes from the com.abhi.xml.jaxb.generated 
    // package.
    JAXBElement<?> fhElement =(JAXBElement<?>)u.unmarshal
    (new FileInputStream("yourfile.xml"));
    FosterHome FH = (FosterHome)fhElement.getValue();
    System.out.println(FH.getDesc());
         // so on ..you can get all elements based on generated objects

} catch( JAXBException je ) {
    je.printStackTrace();
} catch( IOException ioe ) {
    ioe.printStackTrace();
}
1 голос
/ 18 ноября 2011

Это хороший учебник для этого

http://blog.espenberntsen.net/2010/02/26/generate-jaxb-classes-from-an-xsd-schema-and-the-schema-from-an-xml-sample-document/

В нем подробно описано, как сгенерировать схему xsd из файла xml и файл XML, а затем, как использовать эту схему для создания jaxbклассы.В конце вы должны закончить с более чем одним классом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...