How to generate xml in Java? - java

Please, tell me, how to generate XML in Java?
I couldn't find any example using SAX framework.

Try Xembly, a small open source library that wraps native Java DOM with a "fluent" interface:
String xml = new Xembler(
new Directives()
.add("root")
.add("order")
.attr("id", "553")
.set("$140.00")
).xml();
Will generate:
<root>
<order id="553">$140.00</order>
</root>

See this, this, Generating XML using SAX and Java and this

SAX is a library to parse existing XML files with Java. It is not to create a new XML file out of Java. If you want to do this use a library like DOM4J to create a XML tree and then write it to a file.

use dom4j, here is quick start for dom4j
dom4j guide

You can also use libraries like JAXB or SimpleXML or XStream if you want to easily map/convert your java objects to XML.
Say we have a simple entity/pojo - Item.The properties of the pojo class can be made the XML's element or attribute with simple annotations.
#Entity #Root public class Item {
#Attribute
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
#Transient
#ManyToOne
private Order order;
#Element
private String product;
#Element
private double price;
#Element
private int quantity; }
To generate XML from this item, the code can be simply
Serializer serializer=new Persister();//SimpleXML serializer
Item itemToSerializeToXml=new Item(2456L, "Head First Java", 250.00,10);//Object to be serialized
StringWriter destinationXMLWriter=new StringWriter();//Destination of XML
serializer.write(itemToSerializeToXml,destinationXMLWriter);//Call to serialize the POJO to XML
System.out.println(destinationXMLWriter.toString());

I found a nice library for XML creation on GitHub at https://github.com/jmurty/java-xmlbuilder . Really good for simple documents at least (I didn't have an opportunity to employ it for anything bigger than around a dozen lines).
The good thing about this library is that each of its commands (i.e. create attribute, create element, etc.) has 3 levels of abbreviations. For example, to add the tag <foo> to the document you can use the following methods:
.e("foo") (single-letter form)
.elem("foo" (4 letter form)
.element("foo") (fully spelled-out form)
This allows creating XML using both longer and more abbreviated code, as appropriate, so it can be a good fit for a variety of coding styles.

Related

JAXB Without Defining Class or Annotations

I would like to use JAXB to read and write only a few parts of a very large XML. I would like to be able to do this without having to define a root object class for every element and attribute in the XML. The example below outlines what I need:
I have the XML
<A>
<B/>
<C/>
<D/>
</A>
I would like to use JAXB to get two functions
public String getC() {
...
return C
}
public void writeC(String C) {
... // replaces C value with the paramter C inside the XML
}
Without having to define a new class A with the annotations for B, C, and D.
How can I do this with JAXB? Is there a faster / more efficient way to achieve what I am trying to do than JAXB or a simple File Reader and Writer?
The purpose of this is to use a GUI to load and edit config settings that are stored in an XML file. Thank you.
I managed to solve this by using StAX instead. It offered complete flexibility for me to pick out which tags and which attrbitues I needed.
There is a project called EclipseLink MOXy that could solve this type of problem using JAXB. It allows you to map an existing java bean to or from xml and define exceptions from default JAXB using xml or json for the mapping description.

Include unknown XML snipets in JAXB object

I have an application that reads and writes data from/to XML files to/from a DB using JAXB. The "human readability" of these XML files is one of the top priorities in this project as the idea is that XML files from different DBs can be compared to each other.
Now, I have some tables with attributes that hold XML strings themselves which need to be included to my JAXB objects. As I don't have control over these XML strings and readability is key, I helped myself so far with an XmlAdapter that pretty prints the XML from the DB and wraps it in a CDATA element.
The problem of this solution is that the XML string looks a bit lost within the CDATA element and smart text editors with syntax highlighting don't recognize the XML, so they don't highlight the syntax of that XML.
I was wondering therefore if there's a way to "embed" this XML within an element of my JAXB model as if it would be part of the model. So, I need a kind of XmlAdapter that would parse an XML from a String field of my JAXB class and somehow pass the parsing events to the underlying XMLWriter.
I've spent a lot of time looking for a solution combining JAXB and Stax but didn't succeed. In my view I would need some hook exactly between the JAXB and the Stax layer, so that I can customize the events that JAXB sends to the Stax Writers.
Example:
#XmlRootElement
public class MyJaxbModel {
#XmlAttribute
private Integer anAttribute;
#XmlElement
private String xml;
public MyJaxbModel(Integer anAttribute, String xml) {
this.anAttribute = anAttribute;
this.xml = xml;
}
...
}
Then marshalling the following instance of this class
new MyJaxbModel(999, "<?xml version=\"1.0\" encoding=\"UTF-8\"?><element1><child1>bla</child1><child2>ble</child2></element1>");
should result in the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<MyJaxbModel anAttribute="999">
<xml>
<element1>
<child1>bla</child1>
<child2>ble</child2>
</element1>
</xml>
</MyJaxbModel>
Obviously I need it to work also the other way round, i. e. unmarshalling this XML would return me the MyJaxbModel object including the XML string in the xml field.

Xstream: JAVA to XML

I want to create an JAVA object, that could be converted into XML structure
<a id="[numeric value]">[string value]</a>
I read the tutorials on Xstream site and googled some time, but I can't find solutions.
For example, to convert the POJO to
<many_a>
<a id="[numeric value]">
<name>[string value]</name>
</a>
...
</many_a>
I will create POJOs
#XStreamAlias("many_a")
class AList{
#XStreamImplicit(itemFieldName = "a")
List<A> list;
}
class A{
#XStreamAsAttribute
#XStreamAlias("id")
long id;
#XStreamAlias("name")
String name;
}
So, the question is which POJO I should create to get the XML above?
You can use Map<Integer,String> to marshal your object , if you have all entries in your xml as you specified.
Please refer to this question to get an idea.
I found the solution how to solve this issue without writing your custom converter.
See this thread:
XStream: convert collection with attributes

Suggestion to parse this XML in Java

Not new to Java; but relatively new to XML-parsing. I know a tiny bit about a lot of the XML tools out there, but not much about any of them. I am also not an XML-pro.
My particular problem is this... I have been given an XML-document which I cannot modify and from which I need only to parse random bits of it into Java objects. Sheer speed is not much of a factor so long as it's reasonable. Likewise, memory-footprint need not be absolutely optimal either, just not insane. I only need to read through the document one time to parse it, after that I'll be throwing it in the bitbucket and just using my POJO.
So, I'm open to suggestion... which tool would you use?
And, would you kindly suggest a bit of starter-code to address my particular need?
Here's a snippet of sample XML and the associated POJO I'm trying to craft:
<xml>
<item id="...">
...
</item>
<metadata>
<resources>
<resource>
<ittype>Service_Links</ittype>
<links>
<link>
<path>http://www.stackoverflow.com</path>
<description>Stack Overflow</description>
</link>
<link>
<path>http://www.google.com</path>
<description>Google</description>
</link>
</links>
</resource>
<resource>
<ittype>Article_Links</ittype>
<links>
...
</links>
</resource>
...
</resources>
</metadata>
</xml>
public class MyPojo {
#Attribute(name="id")
#Path("item")
public String id;
#ElementList(entry="link")
#Path("metadata/resources/resource/links")
public List<Link> links;
}
NOTE: this question was originally spawned by this question with me trying to solve it using SimpleXml; I'm to the point where I thought maybe someone could suggest a different route to solving the same problem.
Also Note: I'm really hoping for a CLEAN solution... by which I mean, using annotations and/or xpath with the least amount of code... the last thing I want is huge class file with huge unwieldy methods... THAT, I already have... I'm trying to find a better way.
:D
OK, so I settled on a solution that (to me) seemed to address my needs in the most reasonable way. My apologies to the other suggestions, but I just liked this route better because it kept most of the parsing-rules as annotations and what little procedural-code I had to write was very minimal.
I ended up going with JAXB; initially I thought JAXB would either create XML from a Java-class or parse XML into a Java-class but only with an XSD. Then I discovered that JAXB has annotations that can parse XML into a Java-class without an XSD.
The XML-file I'm working with is huge and very deep, but I only need bits and bites of it here and there; I was worried that navigating what maps to where in the future would be very difficult. So I chose to structure a tree of folders modeled after the XML... each folder maps to an element and in each folder is a POJO representing that actual element.
Problem is, sometimes there is an element who has a child-element several levels down which has a single property I care about. It would be a pain to create 4 nested-folders and a POJO for each just to get access to a single property. But that's how you do it with JAXB (at least, from what I can tell); once again I was in a corner.
Then I stumbled on EclipseLink's JAXB-implementation: Moxy.
Moxy has an #XPath annotation that I could place in that parent POJO and use to navigate several levels down to get access to a single property without creating all those folders and element-POJOs. Nice.
So I created something like this:
(note: I chose to use getters for cases where I need to massage the value)
// maps to the root-"xml" element in the file
#XmlRootElement( name="xml" )
#XmlAccessorType( XmlAccessType.FIELD )
public class Xml {
// this is standard JAXB
#XmlElement;
private Item item;
public Item getItem() {
return this.item;
}
...
}
// maps to the "<xml><item>"-element in the file
public class Item {
// standard JAXB; maps to "<xml><item id="...">"
#XmlAttribute
private String id;
public String getId() {
return this.id;
}
// getting an attribute buried deep down
// MOXY; maps to "<xml><item><rating average="...">"
#XmlPath( "rating/#average" )
private Double averageRating;
public Double getAverageRating() {
return this.average;
}
// getting a list buried deep down
// MOXY; maps to "<xml><item><service><identification><aliases><alias.../><alias.../>"
#XmlPath( "service/identification/aliases/alias/text()" )
private List<String> aliases;
public List<String> getAliases() {
return this.aliases;
}
// using a getter to massage the value
#XmlElement(name="dateforindex")
private String dateForIndex;
public Date getDateForIndex() {
// logic to parse the string-value into a Date
}
}
Also note that I took the route of separating the XML-object from the model-object I actually use in the app. Thus, I have a factory that transforms these crude objects into much more robust objects which I actually use in my app.
If your XML documents are relatively small (as appears to be the case here), I would use the DOM framework and XPath class. Here is some boilerplate DOM/XPath code from one of my tutorials:
File xmlFile = ...
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlFile);
XPath xp = XPathFactory.newInstance().newXPath();
String value = xp.evaluate("/path/to/element/text()", doc);
// .. reuse xp to get other values as required
In other words, basically you:
get your XML into a Document object, via a DocumentBuilder;
create an XPath object;
repeatedly call XPath.evaluate(), passing in the path of the element(s) required
and your Document.
As you see, there's a little bit of fiddliness in getting hold of your Document object and like all good XML APIs, it throws a plethora of silly pointless checked exceptions. But apart from that, it's fairly no-nonsense for parsing simple small to medium XML documents whose structure is relatively fixed.
You can use SAXParser or STAXParser. If you can afford some more amount of memory, then you can also afford to use DOMParser. I would advise STAXParser would be best for you.

parse google geocode with xstream

I'm using Java and XStream to parse a google geocode request over http. My idea is to have an Address class with all the geocode attr's (ie. lat/long, city, provice/state etc) but I'm having problems parsing the xml with xstream.
The google response is similar to this:
<?xml version="1.0" encoding="UTF-8" ?>
<kml xmlns="http://earth.google.com/kml/2.0"><Response>
<name>98 St. Patrick St, Toronto</name>
<Status>
<code>200</code>
<request>geocode</request>
</Status>
<Placemark id="p1">
<address>98 St Patrick St, Toronto, ON, Canada</address>
<AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"> <Country><CountryNameCode>CA</CountryNameCode><CountryName>Canada</CountryName><AdministrativeArea><AdministrativeAreaName>ON</AdministrativeAreaName><Locality><LocalityName>Toronto</LocalityName><Thoroughfare><ThoroughfareName>98 St Patrick St</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>M5T</PostalCodeNumber></PostalCode></Locality></AdministrativeArea></Country></AddressDetails>
<ExtendedData>
<LatLonBox north="43.6560378" south="43.6497426" east="-79.3864912" west="-79.3927864" />
</ExtendedData>
<Point><coordinates>-79.3896388,43.6528902,0</coordinates></Point>
</Placemark>
</Response></kml>
That doesn't show up very well, but the meat of the code is in the AddressDetails tag.
Anyway, I'm new to Java and XStream so the API terminology is a bit confusing for me. I just need to be able to write some mapper that maps all these tags (ie. CountryName) to an attribute within my Address object, (ie. address.country = blah) The address object will be pretty simple, mainly just strings for country name etc and floats for lat/long.
The docs and example just show straight mapping where each xml tag maps directly to the attribute of the same name of the object. In my case however, the tags are named different than the object attr's. A quick point in the right direction is all I'm looking for really.
I've used XStream in several projects. Unfortunately, your problem isn't really what XStream is designed to solve. You might be able to use its converter mechanism to achieve your immediate goal, but you'll run into limitations. In a nutshell, XStream isn't designed to do conversion of Tree Structure A into Tree Structure B -- it's purpose is to convert from a Java domain model into some reasonable XML. XStream is a great tool when you don't care much about the details of the XML produced. If you care more about the XML than the Java objects, look at XMLBeans -- the Java is ugly, but it's incredibly schema-compliant.
For your project, I'd run the Google XML schema through XML beans, generate some Java that will give you a more literate way of hand-coding a converter. You could use a raw DOM tree, but you'd have code like myAddress.setStreet(root.getFirstChild().getAttribute("addr1"))). With XML beans, you say things like myAddress.setStreet(googleResult.getAddress().getStreetName();
I'd ignore JAXB as it's attempt to separate interface from implementation adds needless complexity. Castor might be a good tool to consider as well, but I haven't used it in years.
In a nutshell, there aren't a lot of good Object-to-Object or XML-to-Object converters that handle structure conversion well. Of those I've seen that attempt declarative solutions, all of them seemed much more complicated (and no more maintainable) than using XStream/XmlBeans along with hand-coded structure conversions.
Would it be possible to define a separate class specifically for dealing with XStream's mapping? You could then simply populate your AddressDetails object by querying values out of this other object.
I've ended up just using xpath and populating my own address object manually. Seems to work fine.
Have you tried with json format? It should be the same but you'll need to set a com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver as the driver for XStream
You could use EclipseLink JAXB (MOXy) to do this:
package com.example;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlPath;
#XmlRootElement(name="kml")
public class Address {
private String country;
#XmlPath("Response/Placemark/ns:AddressDetails/ns:Country/ns:CountryName/text()")
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
and
#javax.xml.bind.annotation.XmlSchema(
namespace = "http://earth.google.com/kml/2.0",
xmlns = {
#javax.xml.bind.annotation.XmlNs(
prefix = "ns", namespaceURI ="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0")
},
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.example;
A full example is available here:
http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html

Categories

Resources