Подтвердить что ты не робот

Как разобрать этот XML на Java с помощью JAXB?

У меня есть следующий 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>
4b9b3361

Ответ 1

Вы можете сделать следующее. Используя @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;

}

Семья

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;

}

Demo

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>

Дополнительная информация


UPDATE

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

Вы можете сделать следующее:

    for(Family family : fosterHome.getFamilies()) {
        System.out.println(family.getParentID());
        for(String childID : family.getChildList()) {
            System.out.println("    " + childID);
        }
    }

Ответ 2

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();
}

Ответ 3

Кажется, это хороший учебник для этого

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

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