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
Related
I have recently done an experiment to see how we can use Lombok to reduce boilerplate in our code.
The issue:
When creating a simple data class with a builder through Lombok annotations, in IntelliJ IDEA, I cannot right click a field, then select Analyze Data Flow to Here.
This is using the latest IntelliJ Lombok Plugin. IntelliJ Ultimate 2019.2.3.
Is there any fix for this or is it simply not supported?
Example 1 - no lombok:
public class Person {
private String name;
private int age;
private Person() {
}
public Person(Builder builder) {
name = builder.name;
age = builder.age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public static class Builder {
private String name;
private int age;
public Builder name(String val) {
this.name = val;
return this;
}
public Builder age(int val) {
this.age = val;
return this;
}
public Person build() {
return new Person(this);
}
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person.Builder().name("tom").age(3).build();
}
}
With the above code, when I right click the "name" variable and select analyse dataflow to here, I am able to see the dataflow. As shown in screenshot:
Example 2 - with Lombok:
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
#NoArgsConstructor
#Builder
#Getter
public class Person {
private String name;
private int age;
}
public class Main {
public static void main(String[] args) {
Person person = Person.builder().name("tom").age(3).build();
}
}
With the above code example, selecting 'analyse data flow to here' on the name field will show the variable name, but with no tree to expand as shown in the screenshot.
"Analyze data flow to here" will not work with generated code provided by Lombok annotations.
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;
}
}
If we know the structure of the object the with help of "useAttributeFor" method and aliases we can mapped the same tag name and class variable. But my requirement is that convert the xml file to object without knowing the object structure. For Example we hava a xml file test.xml with contect as:
<test>
<Name>John</Name>
<age>18</age>
</test>
Now I need to convert this xml file into object.
My Java Class will be like:
public class Test
{
private String Name;
private int age;
public void setName(String Name,int age)
{
this.Name = Name;
this.age = age;
}
public void display()
{
System.out.println("Name: "+Name);
System.out.println("Age: "+age);
}
}
I'm new to this so please help me out and thank you all in advance
Suppose you have a requirement to load configuration from xml file.
<test>
<name>John</name>
<age>18</age>
</test>
And you want to load it into Configuration object:
public class Test
{
private String name;
private int age;
public void setName(String name,int age)
{
this.name = name;
this.age = age;
}
public void display()
{
System.out.println("Name: "+name);
System.out.println("Age: "+age);
}
}
you have to do is:
FileReader fileReader = new FileReader("test.xml"); // load your xml file
XStream xstream = new XStream(); // init XStream
// define root alias so XStream knows which element and which class are equivalent
xstream.alias("test", Test.class);
Test test = (Test) xstream.fromXML(fileReader);`
that’s all !
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.