Convert complex XML to Java object - java

i have a xml and i want to save into a string the sub xml formed by the child of a specific tag.
this is a xml example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<SampleDTO>
<id>1</id>
<someList>
<someObject>
<amount>32</amount>
<id>1</id>
<someDescription>I am a description</someDescription>
</someObject>
<someObject>
<amount>66</amount>
<id>2</id>
<someDescription>I am another description</someDescription>
</someObject>
<someObject>
<amount>78</amount>
<id>13</id>
<someDescription>Guess what? I am a description</someDescription>
</someObject>
</someList>
<otherList>
<otherObject>
<flag>true</flag>
<id>1</id>
<otherDescription>Oh nice, a description</otherDescription>
</otherObject>
</otherList>
</SampleDTO>
i want , passing for example "someList" , to save into a String the sub-xml element and value, because next i deserialize it into a java object

use the JAXB unmarshaller for converting xml document into java objects.
firstly add JAXB dependency into your project's classpath. for more info
SampleDTO.java
#XmlRootElement
public class SampleDTO {
private String id;
private List<SomeList> someList;
private List<OtherList> otherList;
#XmlElement
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#XmlElement
public List<SomeList> getSomeList() {
return someList;
}
public void setSomeList(List<SomeList> someList) {
this.someList = someList;
}
#XmlElement
public List<OtherList> getOtherList() {
return otherList;
}
public void setOtherList(List<OtherList> otherList) {
this.otherList = otherList;
}
}
SomeList.java
#XmlRootElement
public class SomeList {
private List<SomeObject> someObject;
#XmlElement
public List<SomeObject> getSomeObject() {
return someObject;
}
public void setSomeObject(List<SomeObject> someObject) {
this.someObject = someObject;
}
}
OtherList.java
#XmlRootElement
public class OtherList {
private List<OtherObject> otherObject;
#XmlElement
public List<OtherObject> getOtherObject() {
return otherObject;
}
public void setOtherObject(List<OtherObject> otherObject) {
this.otherObject = otherObject;
}
}
SomeObject.java
#XmlRootElement
public class SomeObject {
private String amount;
private String id;
private String someDescription;
#XmlElement
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
#XmlElement
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#XmlElement
public String getSomeDescription() {
return someDescription;
}
public void setSomeDescription(String someDescription) {
this.someDescription = someDescription;
}
}
OtherObject.java
#XmlRootElement
public class OtherObject {
private String flag;
private String id;
private String otherDescription;
#XmlElement
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}
#XmlElement
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#XmlElement
public String getOtherDescription() {
return otherDescription;
}
public void setOtherDescription(String otherDescription) {
this.otherDescription = otherDescription;
}
}
Unmarshalling with JAXB
public class Main {
public static void main(String[] args) {
try {
File file = new File("file.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(SampleDTO.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
SampleDTO sampleDTO= (SampleDTO) jaxbUnmarshaller.unmarshal(file);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}

Your java class/object should have at least these 3 instance vars :
private int amount
private int id
private String description
Then use some xml parsing library (eg jdom2), and for each <someObject> tag you iterate through, initialize a new object of your class and assign to it the values parsed from the xml (amount / id / description) , and add each newly created object in a List or array etc..

There are many open-source XML processing packages available.
I like Jackson.
Here is a link to a Baeldung Article about Jackson XML
The summary is this:
Add a Jackson dependency to your POM.
Create an object structure that represents your xml structure.
Create an XmlMapper.
Use the XmlMapper.

Related

Using JAXB, how can I unmarshal into a java object with multiple XmlJavaTypeAdapter references?

I'm trying to use JAXB to unmarshal a data (Polygon) with two #XmlJavaTypeAdapter annotations (Subscriber, Tag) to and from an XML file. Each object has it's own XML file, and the objects are related thus:
Each Subscriber may hold multiple Polygons
Each Polygon may hold multiple Subscribers
Each Polygon may hold multiple Tags
I'm trying to unmarshall the Polygon XML file back to its class object, with its Subscribers and Tags in tact, but can't work out how to do it.
== Subscriber.java ==
#XmlRootElement(name = "Subscriber")
#XmlAccessorType(XmlAccessType.FIELD)
public class Subscriber {
private String ID;
private Set<Polygon> polygons;
#XmlAttribute(name = "ID")
public String getID() {
return this.ID;
}
public void setID(String ID) {
this.ID = ID;
}
#XmlJavaAdapter(PolygonXmlAdapter.class)
#XmlElementWrapper(name = "Polygons")
#XmlElement(name = "Polygon")
public set<Polygon> getPolygons() {
return this.polygons;
}
public void setPolygons(Set<Polygon> polygons) {
this.polygons = polygons;
}
}
== Polygon.java ==
#XmlRootElement(name = "{Polygon}")
#XmlAccessorType(XmlAccessType.FIELD)
public class Polygon {
private String ID;
private Set<Subscriber> subscribers;
private Set<Tag> tags
#XmlAttribute(name = "ID")
public String getID() {
return this.ID;
}
public void setID(String ID) {
this.ID = ID;
}
#XmlJavaAdapter(SubscriberXmlAdapter.class)
#XmlElementWrapper(name = "Subscribers")
#XmlElement(Subscriber)
public Set<Subscriber> getSubscribers() {
return this.subscribers;
}
#XmlJavaAdapter(TagXmlAdapter.class)
#XmlElementWrapper(name = "Tags")
#XmlElement(name = "Tag")
public Set<Tag> getTags() {
return this.tags
}
public void setTags(Set<Tag> tags) {
this.tags = tags;
}
}
== Tag.java ==
#XmlRootElement(name = "Tag")
#XmlAccessorType(XmlAccessType.FIELD)
public class Tag {
private String ID;
#XmlAttribute(name = "ID")
public String getID() {
return this.ID;
}
public void setID(String ID) {
this.ID = ID;
}
}
== SubscriberXmlAdapter.java ==
public class SubscriberXmlAdapter extends XmlAdapter<String, Subscriber> {
private Map<String, Subscriber> subscribers = new HashMap<>();
private Map<String, Subscriber> getSubscribers() {
return subscribers;
}
#Override
public Subscriber unmarshal(String v) throws Exception {
return subscribers.get(v);
}
#Override
public String marshal(Subscriber v) throws Exception {
return v.getID();
}
}
== TagXmlAdapter.java ==
public class TagXmlAdapter extends XmlAdapter<String, Tag> {
private Map<String, Tag> tags = new HashMap<>();
private Map<String, Tag> getTags() {
return tags;
}
#Override
public String unmarshal(String v) throws Exception {
return tags.get(v);
}
#Override
public String marshal(Tag v) throws Exception {
reutrn v.getID();
}
}
== SubscriberCollection.java ==
#XmlRootElement(name = "Subscribers")
#XmlAccessorType(XmlAccessType.FIELD)
public class SubscriberCollection {
private Collection<Subscriber> collection;
#XmlElement(name = "Subscriber")
public Collection<Subscriber> getSubscribers() {
return this.collection;
}
public void setCollection(Collection<Subscriber> collection) {
this.collection = collection;
}
}
== TagCollection.java ==
#XmlRootElement(name = "Tags")
#XmlAccessorType(XmlAccessType.FIELD)
public class TagCollection {
private Collection<Subscriber> collection;
#XmlElement(name="Tag")
public Collection<Tag> getSubscribers() {
return this.collection;
}
public void setCollection(Collection<Subscriber> collection) {
this.collection = collection;
}
}
And to execute the unmarshalling, three xml files - for subscribers, polygons, and tags - containing their respective data are used:
JAXBContext jaxbContext = JAXBContext.newInstance(SubscriberCollection.class, PolygonTagCollection.class, Polygon.class);
unmarshaller subUnmarshaller = jaxbContext.createunmarshaller();
SubscriberCollection subCollection = (SubscriberCollection) subUnmarshaller.unmarshal(new ByteArrayInputStream(subscribersXml.getBytes(StandardCharset.UTF_8.name())));
Unmarshaller tagUnmarshaller = jaxbContext.createUnmarshaller();
TagCollection tagCollectino = (TagCollection) tagUnmarshaller.un,arshal(new ByteArrayInputStream(tagXml.getBytes(StandardCharsets.UTF_8.name())));
Unmarshaller polUnmarshaller = jaxbContext.createUnmarshaller();
SubscriberXmlAdapter subAdapter = new SubscriberXmlAdapter();
for (Subscriber sub : subscriberCollection.getCollection()) {
subAdapter.getCollection().put(sub.getID(), sub);
}
TagXmlAdapter tagAdapter = new TagXmlAdapter();
for (Tag tag : tagCollection.getCollection()) {
tagAdapter.getCollection().put(tag.getID(), tag);
}
polUnmarshaller.setAdapter(SubscriberXmlAdapter.class subAdapter);
polUnmarshaller.unmarshal(new ByteArrayInputStream(polygonXml.getBytes(StandardCharsets.UTF_8.name())));
This unmarshalls the Polygon with the correct subscribers, but not with the correct tags.
I can only set one XmlAdapter to the unmarshaller, so it can only populate the subscribers or the tags within the polygon being unmarshalled.
Is there a way to combine these adapters? Or is there a better way of doing things altogether.
Thanks!

JAXB check if XML-Tag has specific attribute

I'm working at a Method to filter a collection (FileList) of xml-files if a specific xml-tag has an attribute...
In detail... I want to filter all xml-files where the xml-tag has an attribute "is_special", but I've problems to setup my model-classes for the attribute.
At the end I want to store the name of the file and a list of its items, where the value has the attribute is_special="true"
Also I'm using the JAXB Framework with the Moxy extension...
The XML-Structure as followed:
<document>
<id>75C8866AB078DCE541256D16002CF636</id>
<size>806220</size>
<author>xxx</author>
<last_modified>2017.06.12 07:15:41 GMT</last_modified>
<added_to_file>2016.07.05 09:50:44 GMT</added_to_file>
<created>2003.04.28 08:11:06 GMT</created>
<items>
<item>
<name>someName/name>
<type>LNITEMTYPE_DATETIMES</type>
<values>
<value is_special="true"/>
</values>
<last_modified>2003.04.28 08:11:10 GMT</last_modified>
...
</item>
<item>
<name>someName/name>
<type>LNITEMTYPE_TEXT</type>
<values>
<value>SOMETEXT</value>
<value>SOMETEXT</value>
</values>
<last_modified>2003.04.28 08:11:10 GMT</last_modified>
...
</item>
</items>
Therefor I've got 3 Classes for the XML-File...
"XMLDocument.java" implements the list of "Items.java" which implements the list of "Value.java"
XMLDocument.java
#XmlRootElement(name = "notes_document")
public class XMLDocument {
...
private List<Item> items;
...
#XmlElementWrapper(name = "items")
#XmlElement(name = "item")
public List<Item> getItems() {
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
}
item.java
#XmlRootElement(name = "items")
public class Item {
private String name;
private List<String> values;
private boolean valueIsSpecial;
#XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElementWrapper(name = "values")
#XmlElement(name = "value")
public List<String> getValues() {
return values;
}
public void setValues(List<String> values) {
this.values = values;
}
#XmlPath("value/#is_special")
public boolean getValueIsSpecial() {
return valueIsSpecial;
}
public void setValueIsSpecial(boolean valueIsSpecial) {
this.valueIsSpecial = valueIsSpecial;
}
}
value.java
#XmlRootElement(name = "values")
public class Value {
#XmlElement(name = "value")
private String itemValue;
#XmlPath("value/#is_special")
private boolean isSpecial;
public String getValue() {
return itemValue;
}
public void setValue(String value) {
this.itemValue = value;
}
public boolean getValueIsSpecial() {
return isSpecial;
}
public void setValueIsSpecial(boolean isSpecial) {
this.isSpecial = isSpecial;
}
}
My Method so far...
public void FilterTree_isSpecial() throws JAXBException, FileNotFoundException {
for(String file: FileList) {
if (file.endsWith(".xml") && !file.contains("databaseinfo.xml")) {
JAXBContext context = JAXBContext.newInstance(NotesDocumentMetaFile.class);
Unmarshaller um = context.createUnmarshaller();
NotesDocumentMetaFile docMetaFile = (XMLDocument) um.unmarshal(new FileReader(file));
for (int i = 0; i < docMetaFile.getItems().size(); i++) {
// CHECK IF THE <value> OF THIS ITEM HAS ATTRIBUTE is_special
}
}
}
}
Much text... I hope anyone can give me a solution :/
Actually the xpath in your Item.java needs to be : values/value/#is_special like #XmlPath("values/value/#is_special")
If you want the is_special in your Value.java also your xpath should be :
#is_special like : #XmlPath(#is_special)
Also your Item.java, Value.java needs a little change. You don't need #XmlRootElement, you already had it in your XmlDocument.java
Your Item.java should be :
public class Item
{
private String name;
private String type;
private String lastModified;
private List<Value> values;
private String isSpecial;
#XmlPath("values/value/#is_special")
public String getIsSpecial() {
return isSpecial;
}
public void setIsSpecial(String isSpecial) {
this.isSpecial = isSpecial;
}
#XmlElement(name="type")
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#XmlElement(name="last_modified")
public String getLastModified() {
return lastModified;
}
public void setLastModified(String lastModified) {
this.lastModified = lastModified;
}
#XmlElement(name="name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#XmlElementWrapper(name="values")
#XmlElement(name="value")
public List<Value> getValues() {
return values;
}
public void setValues(List<Value> values) {
this.values = values;
}
}
Your Value.java should be :
public class Value
{
#XmlPath("text()")
private String value;
#XmlPath("#is_special")
private String isSpecial;
public String getIsSpecial() {
return isSpecial;
}
public void setIsSpecial(String isSpecial) {
this.isSpecial = isSpecial;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Note that to get value and is_special in Value.java, you could use #XmlPath.
Now you can call getIsSpecial() on Item.java to check if it is special.

Unmarshal One to One Relationships in XML File

When I try to unmarshal my Person.xml to a POJO and print it out the parent object prints out fine but ChildThree.java prints out null?
Test.java
public class Test {
public static void main(String[] args) {
try {
File file = new File("src/xml/person.xml");
System.out.println(file.getAbsolutePath());
JAXBContext jaxbContext = JAXBContext.newInstance(Parent.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
Parent parent = (Parent) jaxbUnmarshaller.unmarshal(file);
System.out.println(parent);
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
Person.xml
<?xml version="1.0" encoding="utf-8"?>
<Parent>
<ChildOne>1</Child>
<ChildTwo>2</Child>
<ChildThree>
<Name>3</Name>
<Age>Ten</Age>
</ChildThree>
</Parent>
Parent.java
#XmlRootElement(name = "Parent")
#XmlAccessorType(XmlAccessType.FIELD)
public class Parent {
#XmlElement
private String ChildOne;
#XmlElement
private String ChildTwo;
#XmlElement
private ChildThree ChildThree;
public String getChildOne() {
return ChildOne;
}
public void setChildOne() {
this.ChildOne = ChildOne;
}
public String getChildTwo() {
return ChildTwo;
}
public void setChildTwo() {
this.ChildTwo = ChildTwo;
}
public ChildThree getChildThree() {
return ChildThree;
}
public void setChildThree() {
this.ChildThree = ChildThree;
}
}
ChildThree.java
#XmlRootElement(name = "ChildThree")
#XmlAccessorType(XmlAccessType.FIELD)
public class ChildThree {
#XmlElement
private String Name;
#XmlElement
private String Age;
public String getName() {
return Name;
}
public void setName() {
this.Name = Name;
}
public String getAge() {
return Age;
}
public void setAge() {
this.Age = Age;
}
}
The following should help:
When you specify #XmlAccessorType(XmlAccessType.FIELD) on your class you should put your annotations on the field (instance variable) and not the property (get/set method), (see: http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html).
Make sure your get/set methods follow the appropriate bean conventions:
String getFoo()
void setFoo(String)
Recognize that JAXB has rules for converting field/property names in Java to XML names that may differ from your expectations. When you have unmarshalling problems it is often useful to populate the object model and marshal it to see what JAXB is expecting (see: http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html).
Fixed it by replacing:
#XmlElement
private ChildThree ChildThree;
with:
#XmlElement(name = "ChildThree")
private List<ChildThree> childThree;

Jackson XML Parsing

Jackson 2.2.3
First, please excuse the stupid mistakes, I'm on a disconnected network, so I had to retype manually)
I have the following XML:
<orgs>
<org name="Test1">
<item>a</item>
<item>b</item>
</org>
<org name="Test2">
<item>c</item>
<item>d</item>
<item>e</item>
</org>
</orgs>
I have the following class to parse this:
#XmlRootElement(name = "orgs")
#XmlAccessorType(XmlAccessType.FIELD)
public class XmlOrgElements {
private List<Org> orgs;
public List<Org> getOrgs() {
return orgs;
}
public void setOrg(List<Org> orgs) {
this.orgs = orgs;
}
public class Org {
#JacksonXmlProperty(isAttribute = true)
private String name;
private List<Item> items;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Item> getItems() {
return items;
}
public void setName(List<Item> items) {
this.items = items;
}
}
public class Item {
#JacksonXmlText
private String item;
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
}
}
But all I'm getting back is "orgs=null". Does anyone know why?
You need to enable unwrapped handling for lists; default is to use "wrapped" format. The best way to diagnose this problem is to start with Java objects, serialize as XML, and see what the output format is.
This gives an idea of how structure differs.
If you want to default to unwrapped style, you can use:
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
mapper.registerModule(module);
There is also an annotation #JacksonXmlElementWrapper:
public class Bean {
#JacksonXmlElementWrapper(useWrapping=false)
public List<Stuff> entry;
}
to change behavior on per-list-property basis.
Here is the answer for those reading along:
#JacksonXmlRootElement(localname = "orgs")
public class Orgs {
#JacksonXmlElementWrapper(useWrapping = false)
private List<Org> org;
public List<Org> getOrg() {
return org;
}
public void setOrg(List<Org> org) {
this.orgs = org;
}
public Orgs() {}
}
public class Org {
#JacksonXmlProperty(isAttribute = true)
private String name;
#JacksonXmlElementWrapper(useWrapping = false)
private List<String> item;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getItem() {
return item;
}
public void setItem(List<String> item) {
this.item = item;
}
}

xStream parsing XML with duplicate tags

I have XML structure as below:
<Groups>
<Products>
<Product>
<Name>One</Name>
</Product>
<Product>
<Name>Two</Name>
</Product>
</Products>
<OtherProducts>
<Product>
<Id>1</Id>
</Product>
<Product>
<Id>2</Id>
</Product>
</OtherProducts>
</Groups>
I am trying to parse this using XStream, with the following classes:
#XStreamAlias("Groups")
class GroupData {
List<Product> Products;
List<OtherProduct> OtherProducts;
}
#XStreamAlias("Product")
class Product {
String name;
}
#XStreamAlias("Product")
class OtherProduct {
int id;
}
And therein lies the problem -- the parser tries to convert the "Product" items using the "OtherProduct" class.
I believe there must be some way of specifying the class to use to parse an XML object, but I can't make heads or tails of the XStream attributes.
Any help would be greatly appreciated.
The solution is not straighforward.
The marshal (Object to XML) is quite simple, the problem comes when you have to unmarshal (XML to Object) it.
What happens is that when XStream starts reading the XML and it finds a Product tag, it can't know for sure if it is a "Product" or "OtherProduct" object, since the tag name is the same.
So, you have to teach XStream to look ahead and check for something that you know that makes them different. In that case, the inner attributes "Name" and "Id".
You can teach XSTream how to do that writing Converters.
The solution above shows how to solve the problem.
Product class:
#XStreamAlias("Product")
public class Product {
#XStreamAlias("Name")
private String name;
public Product() {
}
public Product(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
OtherProduct class:
#XStreamAlias("Product")
public class OtherProduct {
#XStreamAlias("Id")
private int id;
public OtherProduct() {
}
public OtherProduct(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
GroupData class:
#XStreamAlias("Groups")
public class GroupData {
#XStreamAlias("Products")
private List<Product> products = new ArrayList<>();
#XStreamAlias("OtherProducts")
private List<OtherProduct> otherProducts = new ArrayList<>();
public void add(Product product) {
getProducts().add(product);
}
public void add(OtherProduct otherProduct) {
getOtherProducts().add(otherProduct);
}
public List<Product> getProducts() {
return products;
}
public List<OtherProduct> getOtherProducts() {
return otherProducts;
}
}
ProductConverter class:
public class ProductConverter implements Converter {
private ProductUnmarshaller productUnmarshaller = new ProductUnmarshaller();
#Override
public boolean canConvert(#SuppressWarnings("rawtypes") Class clazz) {
return clazz.equals(Product.class);
}
#Override
public void marshal(Object object, HierarchicalStreamWriter hsw, MarshallingContext mc) {
Product product = (Product) object;
hsw.startNode("Name");
hsw.setValue(product.getName());
hsw.endNode();
}
#Override
public Object unmarshal(HierarchicalStreamReader hsr, UnmarshallingContext uc) {
return productUnmarshaller.unmarshal(hsr, uc);
}
}
OtherProductConverter class:
public class OtherProductConverter implements Converter {
private ProductUnmarshaller productUnmarshaller = new ProductUnmarshaller();
#Override
public boolean canConvert(#SuppressWarnings("rawtypes") Class clazz) {
return clazz.equals(OtherProduct.class);
}
#Override
public void marshal(Object object, HierarchicalStreamWriter hsw, MarshallingContext mc) {
OtherProduct otherProduct = (OtherProduct) object;
hsw.startNode("Id");
hsw.setValue(Integer.toString(otherProduct.getId()));
hsw.endNode();
}
#Override
public Object unmarshal(HierarchicalStreamReader hsr, UnmarshallingContext uc) {
return productUnmarshaller.unmarshal(hsr, uc);
}
}
ProductUnmarsheller class:
public class ProductUnmarshaller {
public Object unmarshal(HierarchicalStreamReader hsr, UnmarshallingContext uc) {
hsr.moveDown();
String nodeName = hsr.getNodeName();
String nodeValue = hsr.getValue();
hsr.moveUp();
if ("Name".equals(nodeName)) {
return new Product(nodeValue);
} else if ("Id".equals(nodeName)) {
return new OtherProduct(Integer.parseInt(nodeValue));
} else {
return null;
}
}
}
And finally, a class using it all:
public class ProductTest {
#Test
public void test() {
Product productOne = new Product("One");
Product productTwo = new Product("Two");
OtherProduct otherProduct1 = new OtherProduct(1);
OtherProduct otherProduct2 = new OtherProduct(2);
GroupData group = new GroupData();
group.add(productOne);
group.add(productTwo);
group.add(otherProduct1);
group.add(otherProduct2);
XStream xs = new XStream();
xs.processAnnotations(GroupData.class);
xs.processAnnotations(OtherProduct.class);
xs.processAnnotations(Product.class);
xs.registerConverter(new ProductConverter());
xs.registerConverter(new OtherProductConverter());
String xml = xs.toXML(group);
System.out.println(xml);
GroupData gd = (GroupData) xs.fromXML(xml);
for (Product product: gd.getProducts()) {
System.out.println(product.getName());
}
for (OtherProduct otherProduct: gd.getOtherProducts()) {
System.out.println(otherProduct.getId());
}
}
}

Categories

Resources