APP NEWS--RIM says app interest actually really high
http://t.co/iNIMbdYW
ZDNet is available in the following editions:
You can read and manipulate XML documents in Java much easier by using XmlBeans. We show you how to get started.
Let's start with XmlBeans, now at version 2.0. XmlBeans originated within BEA and was donated to Apache. The world is full of XML/Java data binding tools; what makes XmlBeans different is that it is useful to many if not most classes of XML related coding, from low level node traversal over non-data elements (so you can dig out those comments programmatically) to abstracted data oriented manipulation.
Working with XmlBeans starts with an XML Schema. Let's take an example schema for a simple application, sites.xsd. You'll find this, with the rest of the examples in this article in the download for this article.
Our example schema specifies a schema with a "sites" element, which can contain a number of "site" elements, which in turn can contain any number of "rating" or "comment" elements which both have an email address as an attribute for identifying the author of the rating or comment.
Get XmlBeans from the Apache Web site and install it. Remember to set the enviroment variable XMLBEANS_HOME to where you install it and add the $XMLBEANS_HOME/bin directory from the distribution to your path. This will make the XmlBeans commands available, most important of these being "scomp", the schema compiler.
Now if we run
scomp -out sites.jar sites.xsd
We get to see
Time to build schema type system: 1.185 seconds Time to generate code: 0.131 seconds Time to compile code: 1.179 seconds Compiled types to: sites.jar
Scomp has built a type system, generated Java code for it and compiled it. We only get a sites.jar file as output because unless told not to, scomp just generates the precompiled jar file. If you want to see the source of the code it generates, you can run
scomp -srconly -src srcdir sites.xsd
Now we can see what has been created. The generated classes are all in the com.example.sites.site package; this has been derived from the target namespace of the schema. This is defined in the opening lines of the schema file:
<?xml version="1.0" encoding="utf-8"?>
<?xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:si="http://www.example.com/sites/SITE"
targetNamespace="http://www.example.com/sites/SITE"
elementFormDefault="qualified">
If your schema doesn't have a target namespace, the generated classes will appear in a package called noNamespace. For the example, we have a SitesDocument class, and classes for each of the types defined in the schema, Sites, Site, Comment, Rating and Email. All of these generated classes extend the XmlBeans foundation class, XmlObject. We'll get back to that but for now we'll get straight to parsing a XML document...
import com.example.sites.site.*;
import java.io.*;
import org.apache.xmlbeans.*;
public class Example1 {
public static void main(String[] args) {
try {
SitesDocument sd=SitesDocument.Factory.parse(new
File("./sites.xml"));
/* ......... */
}
catch (IOException e) {
System.err.println("IOException:"+e);
}
catch (XmlException e) {
System.err.println("XmlException:"+e);
}
}
}
...and that's it. Problems in parsing will throw an XmlException. We are ready to do some processing. All of the generated classes have a static Factory to allow for the creation of instances, either by parsing or programmatic creation. Here we've used the simplest parse method in the factory.
Let's add some code to iterate through the site entries and print out the comments and ratings. First we need to get the root element of our document.
Sites sites=sd.getSites();
Sequences in XML Schemas are represented by arrays in XmlBeans, so we can take that array and iterate through it (note that we're using Java SE 5.0's new for construct);
for(Site s:sites.getSiteArray()) {
Elements and their attributes have methods generated for them to allow you to get and set their values; let's get the src attribute of our site and print it.
System.out.println(s.getSrc());
And in the same way, we can get the Rating and Comment arrays within the Site element and iterate through them.
for(Rating r:s.getRatingArray()) {
System.out.println(r.getEmail() + " rated the site "
+ r.getRated() + " on " + r.getRatedon());
}
for(Comment c:s.getCommentArray()) {
System.out.println(c.getEmail() + " said "
+ c.getStringValue());
}
}
The next obvious thing to do is to manipulate the XML. Let's add a site to the document.
Site newsite=sites.addNewSite();
Again, XMLbeans' scomp has generated methods to allow you to create an empty Site instance and add it to the Sites instance. All we need to do now is set the "src" attribute...
newsite.setSrc("http://www.example.net/specialpurpose.html");
You can also address sequences by index number, for example, if we wanted to insert a Comment at the start of the Site element's contents, then you can use
Comment newcomment=newsite.insertNewComment(0);
...which creates and inserts an empty Comment at the 0th position. All you need to do now is set its attribute and value.
newcomment.setEmail("fred@example.com");
newcomment.setStringValue("This was a reasonable addition");
After all this manipulation, we would reasonably want to save the document.
sd.save(new File("./newsites.xml"));
With the example source that comes with this article, you'll find all the above code in Example1.java. Before you can run it, you'll need to copy xbean.jar and jsr173_api.jar from the XmlBeans distribution, and the sites.jar file we generated earlier, into the lib directory. All you need to do then run "ant example1" and you should have a newsites.xml file in the directory.
If you look at the newsites.xml file, you'll see a demonstration of how XmlBeans preserves the XML Infoset. The file has been modified, but you'll note that comments in the sites.xml file have not been removed from the file but have been kept in place. This is incredibly useful attribute when you need to process XML files without losing any content of the files, for example when you are manipulating files which go through a version control system, and it is something that is not usually achievable with other XML mechanisms which decant XML content away from the DOM.
As mentioned earlier, all the generated classes are based on XmlObject. It's XmlObject which provides more navigation and validation options. XmlBeans operates by default without validation, but by calling the validate() method on an XmlBean, you can test the validity of the contents of any bean, including its children. The validation includes the XML Schema restrictions if they are defined. In our example sites.xsd file, we have a restriction on the Email type to ensure that only valid email addresses are entered. We can create an instance of the Email class using its factory, set it to a value and then validate it.
Email email=Email.Factory.newInstance();
email.setStringValue("email@example.com");
if(!email.validate()) { .... }
In the examples you'll find Validate.java which uses this to test an array of email addresses. This isn't the only validation mechanism in XmlBeans; you can have a validation error listener which can gather up all the validation errors in one location, or you can turn on validation on setting though this is really only used for debugging.
To navigate around a document, you can use XML Cursor to traverse from any XmlObject. Just request a cursor from an object, so if we navigate to the first site element in our example file:
String stnamespace="http://www.example.com/sites/SITE";
SitesDocument sd=SitesDocument.Factory.parse(new File("./sites.xml"));
Site site=sd.getSites().getSiteArray()[0];
XmlCursor cursor=site.newCursor();
This cursor now points to the site element and with this cursor we can navigate relative to this; for example, if we want the first element child then we can move the cursor like so
cursor.toChild(stnamespace,"rating");
XmlCursors are most useful when you want the ability to traverse the document at a token level, though you can get down to character by character level. If you want to get a feel for how a document looks to an XmlCursor, the next example (CursorWalk.java) parses a document and walks through the document, printing what it finds;
XmlObject sd=XmlObject.Factory.parse(new File("./sites.xml"));
XmlCursor sdcursor=sd.newCursor();
while(sdcursor.hasNextToken()) {
sdcursor.toNextToken();
if(sdcursor.isText()) {
System.out.println(sdcursor.currentTokenType()
+ " " + sdcursor.getChars());
} else {
System.out.println(sdcursor.currentTokenType()
+ " " + sdcursor.getName());
}
}
Notice here for the first time, we've not used the SiteDocument class we generated with scomp, and instead have used the XmlObject directly allowing us to parse any well formed XML file without a schema file.
The other way to navigate in XmlBeans goes to the opposite end of the abstraction spectrum; the ability to select and query using XPath/XQuery expressions, giving you the ability to query the document and select from the nodes within it. XmlObjects support selectPath() and execQuery() methods. The selectPath() is purely for selecting nodes in the document, whereas the execQuery() method lets you run XQuery and can create completely new XML as its return data.
To use this capability you will need to add two more libraries to your classpath, the Saxon library, but more specifically the 8.1.1 version, and the xbean_xpath.jar from the XmlBeans distribution. You'll find a link to the right version of Saxon at the XmlBeans site; take the saxon8.jar from the Saxon distribution and the xbean_xpath.jar file and copy them to the lib directory of the example source.
For a simple demonstration of using XPath queries, there's SimpleXPath.java; let's look at the relevant part of the source;
String namespace="declare namespace st='http://www.example.com/sites/SITE';";
XmlObject[] sitelist=sd.selectPath(namespace+"//st:site[st:rating/@rated=5]");
for(Site site:(Site[])sitelist) System.out.println(site.getSrc());
The first part is some XQuery to declare the namespace. This will be prepended to the query. Then we have the selectPath() call; selectPath() and execQuery() both return an array of XmlObjects. The actual XPath is
//st:site[st:rating/@rated=5]
which says select any site element which contains a rating element with a rated attribute of 5. We get back an array of XmlObjects, which we can cast to an array of Sites and print the results.
XPath and XQuery are a whole separate topic, but suffice to say they open the way for XmlBeans to perform some pretty nifty queries and document generation without descending the hierarchy of schema classes, but without losing the facilities offered by the XmlBeans generated classes.
XmlBeans is an excellent option if you are looking for a one stop shop for your XML mangling needs. If you are wondering "but won't I always need an XML Schema", although it can't fine tune a schema like hand coding can, XmlBean's inst2xsd tool can take a number of XML files and attempt to generate a .xsd file for you.
In the next article, we'll look at E4X, which is built on the foundation that is XmlBeans and use both together to access a Web based information service.
DJ Walker-Morgan is a consulting developer, specialising in Java and user-to-user messaging and conferencing.
APP NEWS--RIM says app interest actually really high
http://t.co/iNIMbdYW
EU News: New standards make using carrier Wi-Fi super easy: Joining a carrier Wi-Fi hot spot on your... http://t.co/trMYbugj #smartphone
11 minutes ago by smarthack on twitterHome telepresence demand to grow despite hiccups http://t.co/1yz8tSdK
11 minutes ago by ArkadinAPAC on twitterNew standards make using carrier Wi-Fi super easy - Zd Net http://t.co/qnOpOtzd: another industry group called th... http://t.co/GfSsPkzz
56 minutes ago by roaming on twitterFirst 'biological computer' created, can read DNA http://t.co/WQj84thX
56 minutes ago by _Sandeep_Singh on twitterAsian data centers eyeing cloud services http://t.co/XVvRM4WH #CLOUD #asia
56 minutes ago by HostingInAsia on twitterAlibaba raising $3B to buy back Yahoo stake. http://t.co/zSARnaLU
1 hour ago by PCDoctor_Kam on twitter中国 - http://t.co/gZPcUzEm: BEIJING--An officer at the Beijing Internet Information Office (BIIO) has decreed… http://t.co/h22vsxH6 | #ZHPR
1 hour ago by PairsonnalitesA on twitter#China: New identity data regulation in microblogs will be implemented by Mar 16 #weibo http://t.co/aSvhy5b5 ^SP
1 hour ago by article19asia on twitterJudge: Chinese engineer didn't spy on US. http://t.co/AiuXL8H3
1 hour ago by PCDoctor_Kam on twitterRT @Cyber_War_News: Hacker denied $50K payout, releases code - ZDNet Asia News http://t.co/nvBbIjhj
1 hour ago by Netzblockierer on twitterRT @article19asia: #China: New identity data regulation in microblogs will be implemented by Mar 16 #weibo http://t.co/aSvhy5b5 ^SP
1 hour ago by myfriendpillay on twitterRT @Cyber_War_News: Hacker denied $50K payout, releases code - ZDNet Asia News http://t.co/nvBbIjhj
3 hours ago by RenegadeRouge on twitterNice research and pardon If there are some major issues which make cloud security trembling & risky.. 1. Abuse and Nefarious Use of Clo...
5 hours ago by evabrian on Cloud, mobility to drive security marketNice research and pardon If there are some major issues which make cloud security trembling & risky.. 1. Abuse and Nefarious Use of Clo...
5 hours ago by evabrian on Cloud to drive industry, security concerns remainTechnology Innovation, Strategy & Integration for CIOs and IT professionals in Asia Pacific
The 3rd BankTech Executive Summit 2012
Feb 9 Hong Kong & Feb 15 Singapore. The Future Vision of Banking & Financial Services.
Asian Financial Services Congress 2012 - The 2012 Agenda: Solutions for Disruptive Times
23 - 24 Feb, Marina Bay Sands (SG). Register today!
Mobile Marketing in Indonesia Conference
23-24 Feb 2, Jakarta. For more information, visit www.conferences.com.sg/conf-mmi.htm
ZDNet Asia Intelligent Singapore video series
Featuring inteviews with CXOs who define "intelligence" in their markets and reveal how their companies drive business efficiencies through ICT.