Suggesstion needed for persisting java objects to xml - java

We are using hibernate to load data from oracle database. I need to load the data from one of the tables and then store selected data from this table as an xml file in another table. It would be great if someone could suggest, what would be the best way to achieve this functionality?

Take a look at this question which discusses libraries (such as JAXB and XStream) you can use to convert Java objects to XML.
What is the best way to convert a java object to xml with open source apis

Use Xstream of ThougthWorks.
"XStream is a simple library to serialize objects to XML and back again."

XMLEncoder (java.beans.XMLEncoder) is already included in the JDK and enables you to persist java objects to XML without any external libraries or tools.
An example class:
public class Foo {
private String foo ;
public void setFoo(String s) {
foo = s;
}
public String getFoo() {
return foo;
}
}
Helper class to serialize to XML:
import java.beans.XMLEncoder;
import java.io.*;
public class FooHelper {
public static void write(Foo f, String filename) throws Exception{
XMLEncoder encoder =
new XMLEncoder(
new BufferedOutputStream(
new FileOutputStream(filename)));
encoder.writeObject(f);
encoder.close();
}
}
The resulting XML:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.5.0-beta" class="java.beans.XMLDecoder">
<object class="Foo">
<void property="foo">
<string>bar</string>
</void>
</object>
</java>

If you are using JPA to persist your entities then look at if you can switch your provider to EclipseLink. If can convert the the same JPA persistent pojos to XML for you. So you will only have to deal with single library.

You can take a look at xmlbeans

Related

Alternative Entity-Conversion with XStream

We are using XStream to serialize and deserialize entities. If the entities are persisted, they have an ID and the serialized form of the object is the ID only which could look like:
<Person>4</Person>
"Deserialization" is simply the read operation from the database.
This works pretty good implementing a SingleValueConverter which uses a DAO to load the entity:
public class TestSerializer implements SingleValueConverter {
public Object fromString(String str) {
return dao.readById(str);
}
public String toString(Object obj) {
return ((Entity) obj).getId();
}
}
But in some cases the entities which have to be serialized are not persisted. So they do not have an ID and I have to do a "real" serialization. Since XStream knows how to serialize many objects on it's own and I do not care about the structure of the XML outcome, it would be fine if i could get something like this:
<Person>
<name>Jon Doe</name>
</Person>
So is it possible in a custom Converter-implementation to do this serialization and deserialization?
In a converter you are free to do conversion in any way you like. So basically you can decide in your custom converter how you want to (de-)serialize the object. However, AFAIK you cannot switch between single-value-conversion/normal conversion. But your example XML implies this.
If you just want to delegate to another converter like XStream's ReflectionConverter, you could do this with the convertAnother(Object, Converter)-method (see also this question/answer). For this, you have to implement the Converter interface instead of SingleValueConverter, to get access to the (un-)marshalling context.
Does this answer your question?
hth,
- martin
Underscore-java can read and write xml files. I am the maintainer of the project.

to split a String from an XML file

i'm reading an xml file which contain the attributes of many objects of a Class; I'm using a DOM xml parser; in this Class there is also an array field (NEARBOXID), so I would know if is a good way to read it from the xml file like a single String and then split its content, or is there any better way to do this?
the file is like this:
<CONFIGURATION>
<CONFIG>
<BOXID>1</BOXID>
<LENGTH>100</LENGTH>
<NEARBOXID>2,3,4,5</NEARBOXID>
</CONFIG>
<CONFIG>
<BOXID>2</BOXID>
<LENGTH>200</LENGTH>
<NEARBOXID>1,8</NEARBOXID>
</CONFIG>
You should read as string and split it. Using a loop convert the numbers into integer using ParseInt
No, it's up to you to split that field. The String.split method will do it just fine.
You need to extract the complete data within the required tag using XPath, and later use String.split(), to get the desired values out of the complete string.
Since you are converting your XML to Java objects, I will demonstrate how this could be done using a JAXB (JSR-222) implementation. A JAXB implementation is included in the JDK/JRE starting with Java SE 6.
I would recommend changing the contents of the NEARBOXID element to be space separated.
<NEARBOXID>2 3 4 5</NEARBOXID>
The corresponds to the following entry in an XML schema. This means that you could validate that the element contains space separated int values instead of space separated Strings.
<xs:element name="NEARBOXID" minOccurs="0">
<xs:simpleType>
<xs:list itemType="xs:int"/>
</xs:simpleType>
</xs:element>
Config
Then you could map the element using JAXB's #XmlList annotation (see: http://blog.bdoughan.com/2010/09/jaxb-collection-properties.html).
import javax.xml.bind.annotation.*;
#XmlAccessorType(XmlAccessType.FIELD)
public class Config {
#XmlElement(name="BOXID")
private int boxId;
#XmlElement(name="LENGTH")
private int length;
#XmlElement(name="NEARBOXID")
#XmlList
private int[] nearBoxIds;
}
Configuration
The object below would map to the root of your XML document.
import java.util.List;
import javax.xml.bind.annotation.*;
#XmlRootElement(name="CONFIGURATION")
#XmlAccessorType(XmlAccessType.FIELD)
public class Configuration {
#XmlElement(name="CONFIG")
private List<Config> configs;
}
Demo
Below is some demo code to prove that everything works.
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Configuration.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum14305301/input.xml");
Configuration configuration = (Configuration) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(configuration, System.out);
}
}
input.xml/Output
Below is the input to and output from running the demo code.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<CONFIGURATION>
<CONFIG>
<BOXID>1</BOXID>
<LENGTH>100</LENGTH>
<NEARBOXID>2 3 4 5</NEARBOXID>
</CONFIG>
<CONFIG>
<BOXID>2</BOXID>
<LENGTH>200</LENGTH>
<NEARBOXID>1 8</NEARBOXID>
</CONFIG>
</CONFIGURATION>
I think it is a matter of choice. You can use it that way as:
<NEARBOXID>2,3,4,5</NEARBOXID>
or you use it that way:
<NEARBOXID>2</NEARBOXID>
<NEARBOXID>3</NEARBOXID>
<NEARBOXID>4</NEARBOXID>
<NEARBOXID>5</NEARBOXID>
Second way requires you to have different parsing code than the first one, but you can save some code on splitting and dealing with string.
Extract the data as a String and perform split() on it.
Better approach for it is to maintain in individual tags like
<NEARBOXID>2</NEARBOXID>
<NEARBOXID>3</NEARBOXID>
<NEARBOXID>4</NEARBOXID>
<NEARBOXID>5</NEARBOXID>
For parsing the xml query you can use XPath, XQuery or JAXB depending on your requirement.

How to stream XML data using XOM?

Say I want to output a huge set of search results, as XML, into a PrintWriter or an OutputStream, using XOM. The resulting XML would look like this:
<?xml version="1.0" encoding="UTF-8"?>
<resultset>
<result>
[child elements and data]
</result>
...
...
[1000s of result elements more]
</resultset>
Because the resulting XML document could be big (hundreds of megabytes, perhaps), I want to output it in a streaming fashion (instead of creating the whole Document in memory and then writing that).
The granularity of outputting one <result> at a time is fine, so I want to generate one <result> after another, and write it into the stream. In other words, I'd simply like to do something like this pseudocode (automatic flushing enabled, so don't worry about that):
open stream/writer
write declaration
write start tag for <resultset>
while more results:
write next <result> element
write end tag for <resultset>
close stream/writer
I've been looking at Serializer, but the necessary methods, writeStartTag(Element), writeEndTag(Element), write(DocType) are protected, not public! Is there no other way than to subclass Serializer to be able to use those methods, or to manually write the start and end tags directly into the stream as Strings, bypassing XOM altogether? (The latter wouldn't be too bad in this simple example, but in the general case it would get quite ugly.)
Am I missing something or is XOM just not made for this?
With dom4j I could do this easily using XMLWriter - it has constructors that take a Writer or OutputStream, and methods writeOpen(Element), writeClose(Element), writeDocType(DocumentType) etc. Compare to XOM's Serializer where the only public write method is the one that takes a whole Document.
(This is related to my question about the best dom4j replacement where XOM is a strong contender.)
I ran in to the same issue, but found it's pretty simple to do what you mentioned as an option and subclass Serializer as follows:
public class StreamSerializer extends Serializer {
public StreamSerializer(OutputStream out) {
super(out);
}
#Override
public void write(Element element) throws IOException {
super.write(element);
}
#Override
public void writeXMLDeclaration() throws IOException {
super.writeXMLDeclaration();
}
#Override
public void writeEndTag(Element element) throws IOException {
super.writeEndTag(element);
}
#Override
public void writeStartTag(Element element) throws IOException {
super.writeStartTag(element);
}
}
Then you can still take advantage of the various XOM config like setIdent, etc. but use it like this:
Element rootElement = new Element("resultset");
StreamSerializer serializer = new StreamSerializer(out);
serializer.setIndent(4);
serializer.writeXMLDeclaration();
serializer.writeStartTag(rootElement);
while(hasNextElement()) {
serializer.write(nextElement());
}
serializer.writeEndTag(rootElement);
serializer.flush();
As far as I know, XOM doesn't support streaming directly.
What I used when I wanted to stream my XML documents was NUX, which has Streaming XML Serializer, similar to standard Serializer class in XOM. NUX is compatible with XOM. I downloaded NUX sources, extracted few NUX classes (StreamingSerializer interface, StreamingXMLSerializer -- which works for XOM documents, StreamingVerifier and NamespacesInScope), put them into my project, and it works like a charm. Too bad this isn't directly in XOM :-(
NUX is very nice companion to XOM: http://acs.lbl.gov/software/nux/, working mirror download: nux-1.6.tar.gz
Link to API: http://acs.lbl.gov/software/nux/api/nux/xom/io/StreamingSerializer.html
Here is sample code (methods are called in order: start(), n*nextResult(), finish(), serializer is StreamingXMLSerializer from NUX):
void start() {
serializer.writeXMLDeclaration();
Element root = new Element("response");
root.addAttribute(new Attribute("found", Integer.toString(123)));
root.addAttribute(new Attribute("count", Integer.toString(542)));
serializer.writeStartTag(root);
serializer.flush();
}
void nextResult(Result result) {
Element element = result.createXMLRepresentation();
serializer.write(element);
serializer.flush();
}
void finish() {
serializer.writeEndTag();
serializer.flush();
}

How to easily load a XML-based Config File into a Java Class?

I've got a simple java class that looks something like this:
public class Skin implements Serializable {
public String scoreFontName = "TahomaBold";
...
public int scoreFontHeight = 20;
...
public int blockSize = 16;
...
public int[] nextBlockX = {205, 205, 205, 205};
...
public String backgroundFile = "back.bmp";
...
}
I'd like to read this information from a simple XML file that looks something like this:
<xml>
<skin>
<scoreFontName>"Tahoma Bold"</scoreFontName>
...
<scoreFontHeight>20</scoreFontHeight>
...
<blockSize>16</blockSize>
...
<nextBlockX>
<0>205</0>
<1>205</1>
<2>205</2>
<3>205</3>
<nextBlockX>
....
<backgroundFile>"back.bmp"</backgroundFile>
...
<skin>
</xml>
Is there an easy way to inject the information from the xml file directly into the variable names rather than having to parse it manually? I don't mind using an external library.
Any help is appreciated.
XStream is really great library for just this.
http://x-stream.github.io/
You can set up aliases for your class and even custom data formats to make the XML file more readable.
Alternatives to the already mentioned solutions (XStream and Apache Commons Digester) would be Java's own JAXB for a comparable general approach, or solutions more tailored towards configuration like Apache Commons Configuration or Java's Preferences API.
I would actually recommend Apache Digester, since if your classes are beans, it will just handle reading the XML into them.
You can also use Spring - although it may be a bit of overkill for one class if its for a mobile game!
I've recently started using Simple http://simple.sourceforge.net/ for XML to object mapping. It uses annotations within the class similarly to method I use in C# and is nice and clean.
You can also break up the file into multiple classes and loading saving is a simple one liner.
In your case the Class structure would look like.
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
#Root (Name="skin")
public class Skin {
#Element(name="scoreFontName") // name param not needed if class field is the same as the xml (element) value
private String scoreFontName
#Element
private int scoreFontHeight
#Element
private int blockSize
#ElementArray
private int[] nextBlockX
#Element
private String backgroundFile
// getters
} 
Note one difference is that your array will be saved like this
<nextBlockX>
<int>205</int>
<int>205</int>
<int>205</int>
<int>205</int>
<nextBlockX>
But you you have the option of adding (entry="myName") to the annotation in which came the XML will be saved down like this
<nextBlockX>
<myName>205</myName>
<myName>205</myName>
<myName>205</myName>
<myName>205</myName>
<nextBlockX>
But the end result is the same once it's loaded into the array.
Use JAXB. It is included in the JDK starting with Java 1.6.

XML serialization in Java? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
What is the Java analogue of .NET's XML serialization?
2008 Answer
The "Official" Java API for this is now JAXB - Java API for XML Binding. See Tutorial by Oracle. The reference implementation lives at http://jaxb.java.net/
2018 Update
Note that the Java EE and CORBA Modules are deprecated in SE in JDK9 and to be removed from SE in JDK11. Therefore, to use JAXB it will either need to be in your existing enterprise class environment bundled by your e.g. app server, or you will need to bring it in manually.
XStream is pretty good at serializing object to XML without much configuration and money! (it's under BSD license).
We used it in one of our project to replace the plain old java-serialization and it worked almost out of the box.
"Simple XML Serialization" Project
You may want to look at the Simple XML Serialization project. It is the closest thing I've found to the System.Xml.Serialization in .Net.
JAXB is part of JDK standard edition version 1.6+. So it is FREE and no extra libraries to download and manage.
A simple example can be found here
XStream seems to be dead. Last update was on Dec 6 2008.
Simple seems as easy and simpler as JAXB but I could not find any licensing information to evaluate it for enterprise use.
Worth mentioning that since version 1.4, Java had the classes java.beans.XMLEncoder and java.beans.XMLDecoder. These classes perform XML encoding which is at least very comparable to XML Serialization and in some circumstances might do the trick for you.
If your class sticks to the JavaBeans specification for its getters and setters, this method is straightforward to use and you don't need a schema. With the following caveats:
As with normal Java serialization
coding and decoding run over a InputStream and OutputStream
the process uses the familar writeObject and readObject methods
In contrast to normal Java serialization
the encoding but also decoding causes constructors and initializers to be invoked
encoding and decoding work regardless if your class implements Serializable or not
transient modifiers are not taken into account
works only for public classes, that have public constructors
For example, take the following declaration:
public class NPair {
public NPair() { }
int number1 = 0;
int number2 = 0;
public void setNumber1(int value) { number1 = value;}
public int getNumber1() { return number1; }
public void setNumber2(int value) { number2 = value; }
public int getNumber2() {return number2;}
}
Executing this code:
NPair fe = new NPair();
fe.setNumber1(12);
fe.setNumber2(13);
FileOutputStream fos1 = new FileOutputStream("d:\\ser.xml");
java.beans.XMLEncoder xe1 = new java.beans.XMLEncoder(fos1);
xe1.writeObject(fe);
xe1.close();
Would result in the following file:
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_02" class="java.beans.XMLDecoder">
<object class="NPair">
<void property="number1">
<int>12</int>
</void>
<void property="number2">
<int>13</int>
</void>
</object>
</java>
XMLBeans works great if you have a schema for your XML. It creates Java objects for the schema and creates easy to use parse methods.
If you're talking about automatic XML serialization of objects, check out Castor:
Castor is an Open Source data binding framework for Java[tm]. It's the shortest path between Java objects, XML documents and relational tables. Castor provides Java-to-XML binding, Java-to-SQL persistence, and more.
Usually I use jaxb or XMLBeans if I need to create objects serializable to XML. Now, I can see that XStream might be very useful as it's nonintrusive and has really simple api. I'll play with it soon and probably use it. The only drawback I noticed is that I can't create object's id on my own for cross referencing.
#Barak Schiller
Thanks for posting link to XStream!
Don't forget JiBX.
if you want a structured solution (like ORM) then JAXB2 is a good solution.
If you want a serialization like DOT NET then you could use Long Term Persistence of JavaBeans Components
The choice depends on use of serialization.
public static String genXmlTag(String tagName, String innerXml, String properties )
{
return String.format("<%s %s>%s</%s>", tagName, properties, innerXml, tagName);
}
public static String genXmlTag(String tagName, String innerXml )
{
return genXmlTag(tagName, innerXml, "");
}
public static <T> String serializeXML(List<T> list)
{
String result = "";
if (list.size() > 0)
{
T tmp = list.get(0);
String clsName = tmp.getClass().getName();
String[] splitCls = clsName.split("\\.");
clsName = splitCls[splitCls.length - 1];
Field[] fields = tmp.getClass().getFields();
for (T t : list)
{
String row = "";
try {
for (Field f : fields)
{
Object value = f.get(t);
row += genXmlTag(f.getName(), value == null ? "" : value.toString());
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
row = genXmlTag(clsName, row);
result += row;
}
}
result = genXmlTag("root", result);
return result;
}

Categories