Reputation: 62596
I have the following XML, no XSD or schema with it that I want to parse to java object(s) using JAXB as I heard its better than SAX. Is there a way to accomplish this with annotations or a better way to do this? Does it make it so that i just need a single FosterHome class? I am having trouble finding how to do this any help is grateful.
I was originally thinking of having a FosterHome, Family, and Child class. Using JAXB, is having 3 classes no longer necessary? Im not sure how to deal with this as ChildID shows up in two different areas.
<?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>
Upvotes: 47
Views: 73546
Reputation: 148977
You could do the following. By leveraging @XmlElementWrapper
you can reduce the amount of classes that you require:
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;
}
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);
}
}
Input/Output
<?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>
For More Information
UPDATE
Is there I easy way I can iterate/print out all the ChildID in the Family class?
You could do the following:
for(Family family : fosterHome.getFamilies()) {
System.out.println(family.getParentID());
for(String childID : family.getChildList()) {
System.out.println(" " + childID);
}
}
Upvotes: 70
Reputation: 583
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();
}
Upvotes: 3
Reputation: 7518
This seems to be a good tutorial for doing this
It details how to generate an xsd schema from and xml file and then how to use that schema to genenate jaxb classes. In the end you should end up with more than one class.
Upvotes: 1