|
You are receiving this e-mail because you elected to receive e-mail from Sun Microsystems, Inc. To update your communications preferences, please see the link at the bottom of this message. We respect your privacy and post our privacy policy prominently on our Web site http://sun.com/privacy/ Please do not reply to the mailed version of the newsletter, this alias is not monitored. Feedback options are listed in the footer for both content and delivery issues. |
![]() |
||||||
|
||||||
| In this Issue | ||
Here you'll get tips on using enterprise Java technologies and APIs, such as those in Java 2 Platform, Enterprise Edition (J2EE) and Java Platform, Enterprise Edition (Java EE). This issue covers: » The Schema Validation Framework » More About the Sun Java Streaming XML Parser These tips were developed using the Java 2, Enterprise Edition, v 1.4 SDK. You can download the SDK at http://java.sun.com/j2ee/1.4/download.html. You can download the sample archive for the JAXP 1.3 tip. You can download the sample archive for the Sun Java Streaming XML Parser tip. Any use of this code and/or information below is subject to the license terms. See the Subscribe/Unsubscribe note at the end of this newsletter to subscribe to Tech Tips that focus on technologies and products in other Java platforms. For more Java technology content, visit these sites: java.sun.com - The latest Java platform releases, tutorials, and newsletters. java.net - A web forum where enthusiasts of Java technology can collaborate and build solutions together. java.com - Hot games, cool apps -- Experience the power of Java technology. |
||
| THE SCHEMA VALIDATION FRAMEWORK | ||
by Neeraj Bajaj The Java API for XML Processing (JAXP) 1.3 was initially introduced in Java 2 Platform, Standard Edition (J2SE) 5.0 and is also now available in the Java Web Services Developer Pack (Java WSDP). JAXP 1.3 adds a new Schema Validation Framework (SVF), also called the Validation API, which offers advanced capabilities to efficiently validate XML against a schema. SVF also provides for much faster performance as compared to the schema validation approach in JAXP 1.2. Before examining SVF, let's look at the earlier schema validation approach. Here's a code snippet that demonstrates that approach for SAX parsing:
SAXParserFactory sf = SAXParserFactory.newInstance();
sf.setNamespaceAware(true);
sf.setValidating(true);
SAXParser sp = sf.newSAXParser();
sp.setProperty(
SCHEMA_LANGUAGE, XMLConstants.W3C_XML_SCHEMA_NS_URI);
sp.setProperty(SCHEMA_SOURCE, schema);
sp.parse(new File(xml), dh);
The basic steps are:
Notice that this process couples validation and XML processing. By comparison, in the SVF approach, XML document validation against a schema is decoupled from XML processing. The first step in the SVP approach is to compile the schema:
final String sl = XMLConstants.W3C_XML_SCHEMA_NS_URI;
SchemaFactory factory = SchemaFactory.newInstance(sl);
StreamSource ss = new StreamSource("mySchema.xsd");
Schema schema = factory.newSchema(ss);
Next, you validate an XML document against the schema. There are three approaches to choose from depending upon your requirements:
All three approaches guarantee that the XML document is validated only against the schema from which the
Lets look at the first approach, setting the SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setSchema(schema); SAXParser parser = spf.newSAXParser(); parser.parse(<XML DOCUMENT>);
Here, the same
After you load a Validator v = schema.newValidator(); v.validate(new StreamSource(xml));
The Validator v = schema.newValidator(); v.validate(new DOMSource(<DOM NODE>));
You might consider the
The third approach is to create a specially-designed SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); XMLReader reader = spf.newSAXParser().getXMLReader(); ValidatorHandler vh = schema.newValidatorHandler(); //key is to set "ValidatorHandler" as ContentHandler //so that SAX event can be validated reader.setContentHandler(vh); reader.parse(xml);
Notice that to validate the SAX events, you need to set the
Using a SAXOutputter so = new SAXOutputter(vh); so.output(jdomDocument);
The There are other things you can do using the SVF, such as validate XML after transformation or obtain schema type information. For more information about using the SVF see the article Easy and Efficient XML Processing: Upgrade to JAXP 1.3 Running the Sample Code
A sample package accompanies this tip. The code in the sample package includes code examples and demonstrates the techniques covered in the tip. There are additional samples in this package. For example, one of the samples compares the schema validation performance using the new SVF and the previous approach of setting two schema properties. Another sample shows how to validate the output of a
About the Author Neeraj Bajaj is a Member of Technical Staff in Web Technology and Standards at Sun Microsystems. He is the architect of the Sun Java Streaming XML Parser and the co-lead of the JAXP 1.4 specification. In addition to his contributions to StAX and JAXP 1.4, Neeraj has contributed to the development of JAXP 1.2 (JSR 60) and JAXP 1.3 (JSR 206). Back to Top |
||
| MORE ABOUT THE SUN JAVA STREAMING XML PARSER | ||
|
by Kim LiChong The February 22, 2005 Tech Tip Introducing the Sun Java Streaming XML Parser outlined the differences between the Sun Java Streaming XML Parser (SJSXP) and two API libraries for working with XML: the Simple API for XML (SAX) and the Document Object Model (DOM) libraries. Briefly, SJSXP is an implementation of the Streaming API for XML parsing (StAX) -- JSR173. As an implementation of StAX, SJSXP enables XML infosets to be transmitted and parsed serially during an application's runtime. SJSXP allows you to "pull" nodes from the XML document rather than having them "pushed" from the parser to the application. Consequently, SJSXP is very fast. A whitepaper titled Streaming APIs for XML Parsers shows how the performance of SJSXP compares to other StAX implementations. StAX is part of JAXP 1.4. You can download a standalone JAXP 1.4 implementation from the jaxp project page. SJSXP supports both of the APIs defined by StAX for XML processing: cursor and iterator. The previous Tech Tip on SJSXP included code examples that showed how to use the cursor API to parse and write XML documents. This Tech Tip focuses on the iterator API. It provides code examples that show how to use the iterator API, and general guidelines that describe when to use the iterator API. Comparing the Cursor and Iterator APIs
The cursor API provides a low level representation of SJSXP. It uses a cursor to point to one infoset element from the beginning to the end of a document. The cursor always moves forward through the document. To get this cursor-based, forward-only access to XML, you use two interfaces: public int getEventType() returns an integer code that identifies the type of event that the parser found under the cursor. An example of an event is the start of an XML element or the end of the document. The following method: public String getText(); gets text from the XML item that the cursor is pointing to.
All of the XML information retrieved is returned as strings, much like information retrieved by SAX. Each event is represented by an integer constant. For example, the constant for the start of an XML element is
while(parser.hasNext()) {
eventType = parser.next();
switch (eventType) {
case START_ELEMENT:
// Do something
break;
case END_ELEMENT:
// Do something
break;
// And so on ...
}
}
Different methods in By comparison, the iterator API represents the XML document as a set of discrete object events that you pull in the order in which they are read. These event objects are immutable and persistent, and they encapsulate all the associated information about the particular event. There is some overhead in creating each event object, so this approach is not as efficient as using the cursor API. As is the case for the cursor API, the iterator API has two APIs for reading and writing:
Note that the DTD, Using
Let's look at some code examples that use
<HockeyTeams xmlns="http://www.myhockey.net">
<Team>
<City>Toronto</City>
<Nickname>Maple Leafs</Nickname>
<Coach>Pat Quinn</Coach>
<Captain>Mats Sundin</Captain>
<Wins year="2003">45</Wins>
<MarketValue currency="USD">280</MarketValue>
</Team>
</HockeyTeams>
You can use the following code to parse the XML document:
URL url = Class.forName("MyClassName").getResource(
"HockeyTeams.xml");
InputStream in = url.openStream();
XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader r = factory.createXMLEventReader(in);
You can iterate through the code with a construct like this:
while(r.hasNext()) {
XMLEvent e = r.nextEvent();
System.out.println(e.toString());
}
If you print each returned <<['http://www.myhockey.net']:: HockeyTeams xmlns:='http://www.myhockey.net'> <['http://www.myhockey.net']::Team> <['http://www.myhockey.net']::City> Toronto </['http://www.myhockey.net']::City> <['http://www.myhockey.net']::Nickname> Maple Leafs </['http://www.myhockey.net']::Nickname> <['http://www.myhockey.net']::Coach> Pat Quinn </['http://www.myhockey.net']::Coach> <['http://www.myhockey.net']::Captain> Mats Sundin </['http://www.myhockey.net']::Captain> <['http://www.myhockey.net']::Wins year='2003'> 45 </['http://www.myhockey.net']::Wins> <['http://www.myhockey.net']::MarketValue currency='USD'> 280 </['http://www.myhockey.net']::MarketValue> </['http://www.myhockey.net']::Team> </['http://www.myhockey.net']::HockeyTeams> ENDDOCUMENT
Each
if(event.getEventType() == event.CHARACTERS) {
Characters chars = event.asCharacters();
System.out.println("chars " + chars.getData() );
}
Or you get element names or attributes from the event, like this:
if(event.getEventType() == event.START_ELEMENT) {
StartElement startE = event.asStartElement();
System.out.println("start" + startE.getName());
Iterator it = startE.getAttributes();
while (it.hasNext()) {
System.out.println(" attributes " + it.next());
}
}
Note that each Using XMLEventWriter
The
XMLEventFactory eventFactory = XMLEventFactory.newInstance();
XMLOutputFactory output = XMLOutputFactory.newInstance();
XMLEventWriter xmlwriter =
output.createXMLEventWriter(System.out);
Notice the difference between using the cursor and iterator APIs. In the cursor API, you use different methods in
In the first line of the following code example, the
xmlwriter.add(eventFactory.createStartDocument("UTF-8","1.0");
//for attributes
Attribute att = eventFactory.createAttribute("year", "2003");
ArrayList attArr = new ArrayList();
attArr.add(att);
//for namespaces
Namespace namespace =
eventFactory.createNamespace("foo","http://www.foo.org");
ArrayList nameArr = new ArrayList();
nameArr.add(namespace);
//order namespace, localname, prefix
QName qname = new Qname (
"http://www.foo.org","HockeyTeam","foo");
//now create the start element
xmlwriter.add(eventFactory.createStartElement(
qname, attArr.iterator(), nameArr.iterator()));
xmlwriter.add(eventFactory.createCharacters(
"Los Angeles Kings"));
xmlwriter.add(eventFactory.createEndElement(
qname, nameArr.iterator()));
xmlwriter.add(eventFactory.createEndDocument());
xmlwriter.flush();
xmlwriter.close();
Deciding When to Use the Cursor or Iterator API The Streaming API for XML chapter in the Java Web Services Developer Pack 1.6 Tutorial lists considerations in deciding between the cursor or iterator API. Here is a summary of those considerations:
For more information on SJSXP, see Chapter 3; Streaming API for XML in the Java Web Services Developer Pack 1.6 Tutorial. Also see the Sun Java Streaming XML Parser release notes. Running the Sample Code A sample package accompanies this tip. The code in the sample package includes some (but not all) of the code examples in the tip, and demonstrates some of the techniques covered in the tip. To install and run the sample:
NOTE: If you do not run these samples with the provided About the Author
Kim LiChong is a Member of Technical Staff in the Java Web
Services Performance Engineering Group at Sun Microsystems. His
interests include XML parsing performance, and is one of the
authors of the StAX 1.0 White Paper: Streaming APIs for XML Parsers. He also is a co-owner of |
||
|
Comments? Send your feedback on the Tech Tips: http://developers.sun.com/contact/feedback.jsp?category=newslet
Subscribe to the following newsletters for the latest information about technologies and products in other Java platforms:
IMPORTANT: Please read our Terms of Use, Privacy, and Licensing policies: http://www.sun.com/share/text/termsofuse.html http://www.sun.com/privacy/ http://developer.java.sun.com/berkeley_license.html ARCHIVES: You'll find the Enterprise Java Technologies Tech Tips archives at: http://java.sun.com/developer/EJTechTips/index.html © 2005 Sun Microsystems, Inc. All Rights Reserved. For information on Sun's trademarks see: http://sun.com/suntrademarks Java, J2EE, J2SE, J2ME, and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. |