I have an XML which looks like below
<Book>
<Name>Book1</Name>
<Cost>20$</Cost>
</Book>
I have used a Bean Class with properties name, cost and successfully unmarshaled the xml file contents to Book bean object.
Now I want to have multiple book objects in the same XML file like below.
<Books>
<Book>
...
</Book>
<Book>
...
</Book>
I know that I can create one more class with Name Books.java and have an arraylist of book objects annotated with #XmlElement tag and unmarshall it.
But, I don't want to waste one more public class for doing that.
Can anyone let me know if there is any other way of parsing that xml file with JaxB.
Thanks in advance.
Found the solution..
I can have a class like below. I can use List list; variable member within the same class Book.java instead of using one more public class Books.java.
#XmlRootElement(name = "Books")
#XmlAccessorType(XmlAccessType.FIELD)
public class BookBean {
private String name;
private String cost;
#XmlElement(name = "Books")
public List<BookBean> books;
public BookBean(){
}
public BookBean(String s1, String s2){
name=s1;
cost=s2;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCost() {
return cost;
}
public void setCost(String cost) {
this.cost = cost;
}
public List<BookBean> getBooks() {
return books;
}
public void setBooks(List<BookBean> books) {
this.books = books;
}
}
Related
I try to unmarshal a xml file to custom classes via jaxb.
The (not changeable) xml file looks as follow:
<demo>
<customers>
<customer usrid="1" name="jane" />
<customer usrid="2" name="leia" />
<customer usrid="3" name="tobi" />
</customers>
<phonenumbers>
<phonenumber usrid="1">123-456-789</phonenumber>
<phonenumber usrid="2">987-654-321</phonenumber>
<phonenumber usrid="2">111-222-333</phonenumber>
</phonenumbers>
<mobilenumbers>
<mobilenumber usrid="3">666-666-666</mobilenumber>
</mobilenumbers>
</demo>
Java classes look something special:
public class Demo {
public List<Customer> customers;
}
public class Customer {
public String usrid;
public String name;
public List<Number> numbers;
}
public class Number {
public NumberType type;
public String value;
}
public enum NumberType {
phone, mobile
}
Is this possible with jaxb (e.g. adapter) or do i have to do a xslt transform first ?
Btw. using jaxb straightforward works fine (annotations omitted):
public class Demo {
public List<Customer> customers;
public List<Phonenumber> phonenumbers;
public List<Mobilenumbers> mobilenumbers;
}
public class Customer {
public String usrid;
public String name;
}
public class Phonenumber {
public String usrid;
public String value;
}
public class Mobilenumber {
public String usrid;
public String value;
}
This is my XML file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<dragonDatabase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<dragon>
<Name>Hackatoo</Name>
<Description>This impulsive and reckless member of the Sharp Class is a master at collecting wood...so long as its axe-like snout doesn't get stuck in the tree its cutting! Hackatoo eggs laid at a high altitude can hook on to whatever they hit.</Description>
<Class>Sharp</Class>
<Fire-Type>No Data</Fire-Type>
<Diet>No Data</Diet>
</dragon>
<dragon>
<Name>Hobblegrunt</Name>
<Description>The Hobblegrunt has a single horn and and an expandable frill surrounding its head. It has clawed wings, small arms and big legs like a Deadly Nadder. It also appears to have long neck and tail as well. The Hobblegrunt doesn't have a particular color, but instead it changes color depending on its mood.</Description>
<Class>Stoker, Boulder</Class>
<Fire-Type>Ethane Expectorant</Fire-Type>
<Diet>No Data</Diet>
</dragon>
</dragonDatabase>
And this is my DragonBean class:
public class DragonBean {
private String name;
private String description;
private String dragonClass;
private String fireType;
private String diet;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDragonClass() {
return dragonClass;
}
public void setDragonClass(String dragonClass) {
this.dragonClass = dragonClass;
}
public String getFireType() {
return fireType;
}
public void setFireType(String fireType) {
this.fireType = fireType;
}
public String getDiet() {
return diet;
}
public void setDiet(String diet) {
this.diet = diet;
}
}
Basically I want to get each dragon in the xml and place it in a list containing the a DragonBean type. I know that I have to parse the XML. But i don't know where to begin. After placing the info in the list I plan to use Jackson to convert it into a JSON file.
Using DocumentBuilderFactory and DocumentBuilder classes, parse the xml file . First get node list of dragon and then iterate over it one by one. Get child nodes in each iteration and then read get text content of those tags and set your model class . will work . Hope it helps!
May be I am repeating this question as compared to previous question(Define namespaces tags so that generated XML have those tags?), but since in my previous question this scope gets limited to XStream that is why I need to ask this new question.
I have two classes People.java and PeopleMain.java
People.java
package com.test;
public class People {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
PeopleMain.java
package com.test;
import com.thoughtworks.xstream.XStream;
public class PeopleMain {
public static void main(String args[]){
People p= new People();
p.setAge("21");
p.setName("Manish Sharma");
String xml = //JAXB code to get xml from Person p object
System.out.println(xml);
}
}
My output on console on running PeopleMain.java comes as:
<com.test.People>
<name>Manish Sharma</name>
<age>21</age>
</com.test.People>
but I want an output as
<People xmlns:ns2="http://example.com/foo" xmlns:ns3="http://example.com/bar">
<ns2:name>Manish Sharma</ns2:name>
<ns3:age>21</ns3:age>
</People>
What changes should I make in my People.java file to get the desired output?
You can do the following and specify the namespace on the #XmlElement annotation:
import javax.xml.bind.annotation.*;
#XmlRootElement(name="People")
#XmlAccessorType(XmlAccessType.FIELD)
public class People {
#XmlElement(namespace="http://example.com/foo")
private String name;
#XmlElement(namespace="http://example.com/bar")
private int age;
}
For More Information
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
http://blog.bdoughan.com/2011/11/jaxb-and-namespace-prefixes.html
http://blog.bdoughan.com/2010/10/how-does-jaxb-compare-to-xstream.html
I am using dom parser in Java.
<Countries>
<Country name="USA" states="50"/>
<Country name="UK" states="4"/>
</Countries>
For the xml given above, if I have USA element node which I want to print as Country[#name="USA"][#states="50"]
Is there an easy way to get this done? Or I have to write custom method ?
If you use DOM parser , You may need to write the custom method to achieve the above feature.
If you go with JAXB , you can do the above feature by overriding the toString method of POJO class.
#XmlRootElement
public class Countries {
#XmlElement
Country country;
}
import javax.xml.bind.annotation.XmlAttribute;
public class Country {
#XmlAttribute
private String name;
#XmlAttribute
private String states;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStates() {
return states;
}
public void setStates(String states) {
this.states = states;
}
#Override
public String toString() {
return "Country[#name="+getName()+"][#states="+getStates();
}
}
Hope this helps you !.
I've read a time ago about generate xml from Java using annotations, but I'm not finding a simple example now.
If I want to make a xml file like:
<x:element uid="asdf">value</x:element>
from my java class:
public class Element {
private String uid = "asdf";
private String value = "value";
}
Which annotations should I use to perform that? (I have a xml-schema, if this helps the generation)
--update
The javax.xml.bind.annotation package have the annotations, "but I still haven't found what I'm looking for": an exemple of usage.. :)
Found it:
import java.io.FileOutputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlRootElement;
public class JavaToXMLDemo {
public static void main(String[] args) throws Exception {
JAXBContext context = JAXBContext.newInstance(Employee.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
Employee object = new Employee();
object.setCode("CA");
object.setName("Cath");
object.setSalary(300);
m.marshal(object, System.out);
}
}
#XmlRootElement
class Employee {
private String code;
private String name;
private int salary;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int population) {
this.salary = population;
}
}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee>
<code>CA</code>
<name>Cath</name>
<salary>300</salary>
</employee>
From: http://www.java2s.com/Code/JavaAPI/javax.xml.bind.annotation/javaxxmlbindannotationXmlRootElement.htm
For the benefit of anyone else hitting this thread, I imagine you did the following:
#XmlRootElement
public class Element {
#XmlAttribute
private String uid = "asdf";
#XmlValue
private String value = "value";
}
For More Information
http://bdoughan.blogspot.com/2011/06/jaxb-and-complex-types-with-simple.html
There are various tools that you can use to do this. XStream (http://x-stream.github.io/) is a reasonably easy tool to use that allows you to use annotations to determine the schema of XML that is created.