Last time, we learned about JAXP, Xerces, DOM and the javax.xml.parsers Java Package. How about getting a little taste of the SAX interfaces? We look at available classes and interfaces, and learn how to use SAX for XML Processing. Given SAX's power, perhaps we can look forward to the day when we'll be translating not just XML, but maybe even Klingon! Maybe not. Before you get started, you'll want to download the support files for this tutorial.
Java and XML Basics, Part 2 - One Last SAX Trick (Page 6 of 6 )
One last trick when it comes to SAX – the SAX specification reads the following under the characters function:
The Parser will call this method to report each chunk of character data. SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks; however, all of the characters in any single event must come from the same external entity so that the Locator provides useful information.
This may not raise any issues with you, but since you took the JAXP path, it means that you are possibly thinking of writing portable code – i.e. XML parser independent; as stated in the previous article, each parser has its own particularities, even if they do share the same set of interfaces (JAXP) – even more so if the interface allows it! So it’s best if you cater for all possible particularities of these beasts. Now, let’s re-read the above paragraph and see what it actually means:
Some SAX parsers might call this function only once and include the whole set of literals found inside a tag, while others may call this function as many times they want with chunks of data – even to the point where they could call this function passing just one single character!
In such cases, our state-machine has to cater for this and paste all these pieces together to form the full string – so really, if we want to be “portable”, we should write our code as it follows (SimpleSAXParser6.java):
public void startElement
( String namespaceURI, String localName, String qName, Attributes atts ) { if( !m_AutomaticSession ) { /** * If not inside a session, keep looking for the "session" tag */ if( qName.equals(SESSION_TAG) ) { /** * If inside a session check the "type" tag
*/ String type = atts.getValue( TYPE_ATTR ); if( (type != null) && type.equals("automatic") ) m_AutomaticSession = true; //we are from now on inside an "automatic" session } } else { /**
* Already in a session, keep looking for the "application" tag
*/ if( qName.equals(APP_TAG) ) { m_Application = true; //from now on print the applications we have found. m_Path = ""; } } }
public void characters( char[] ch, int start, int length ) { if( m_Application ) m_Path += new String( ch, start, length ); //paste this chunk }
In other words, keep building up the String that stores the application path until we are notified that the application element has ended!
DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.