- XML Reference Guide
- Overview
- What Is XML?
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- Table of Contents
- The Document Object Model
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- DOM and Java
- Informit Articles and Sample Chapters
- Books and e-Books
- Implementations
- DOM and JavaScript
- Using a Repeater
- Repeaters and XML
- Repeater Resources
- DOM and .NET
- Informit Articles and Sample Chapters
- Books and e-Books
- Documentation and Downloads
- DOM and C++
- DOM and C++ Resources
- DOM and Perl
- DOM and Perl Resources
- DOM and PHP
- DOM and PHP Resources
- DOM Level 3
- DOM Level 3 Core
- DOM Level 3 Load and Save
- DOM Level 3 XPath
- DOM Level 3 Validation
- Informit Articles and Sample Chapters
- Books and e-Books
- Documentation and Implementations
- The Simple API for XML (SAX)
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- SAX and Java
- Informit Articles and Sample Chapters
- Books and e-Books
- SAX and .NET
- Informit Articles and Sample Chapters
- SAX and Perl
- SAX and Perl Resources
- SAX and PHP
- SAX and PHP Resources
- Validation
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- Document Type Definitions (DTDs)
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- XML Schemas
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- RELAX NG
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- Schematron
- Official Documentation and Implementations
- Validation in Applications
- Informit Articles and Sample Chapters
- Books and e-Books
- XSL Transformations (XSLT)
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- XSLT in Java
- Java in XSLT Resources
- XSLT and RSS in .NET
- XSLT and RSS in .NET Resources
- XSL-FO
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- XPath
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- XML Base
- Informit Articles and Sample Chapters
- Official Documentation
- XHTML
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- XHTML 2.0
- Documentation
- Cascading Style Sheets
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- XUL
- XUL References
- XML Events
- XML Events Resources
- XML Data Binding
- Informit Articles and Sample Chapters
- Books and e-Books
- Specifications
- Implementations
- XML and Databases
- Informit Articles and Sample Chapters
- Books and e-Books
- Online Resources
- Official Documentation
- SQL Server and FOR XML
- Informit Articles and Sample Chapters
- Books and e-Books
- Documentation and Implementations
- Service Oriented Architecture
- Web Services
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- Creating a Perl Web Service Client
- SOAP::Lite
- Amazon Web Services
- Creating the Movable Type Plug-in
- Perl, Amazon, and Movable Type Resources
- Apache Axis2
- REST
- REST Resources
- SOAP
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- SOAP and Java
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- WSDL
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- UDDI
- UDDI Resources
- XML-RPC
- XML-RPC in PHP
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- Ajax
- Asynchronous Javascript
- Client-side XSLT
- SAJAX and PHP
- Ajax Resources
- JSON
- Ruby on Rails
- Creating Objects
- Ruby Basics: Arrays and Other Sundry Bits
- Ruby Basics: Iterators and Persistence
- Starting on the Rails
- Rails and Databases
- Rails: Ajax and Partials
- Rails Resources
- Web Services Security
- Web Services Security Resources
- SAML
- Informit Articles and Sample Chapters
- Books and e-Books
- Specification and Implementation
- XML Digital Signatures
- XML Digital Signatures Resources
- XML Key Management Services
- Resources for XML Key Management Services
- Internationalization
- Resources
- Grid Computing
- Grid Resources
- Web Services Resource Framework
- Web Services Resource Framework Resources
- WS-Addressing
- WS-Addressing Resources
- WS-Notifications
- New Languages: XML in Use
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- Google Web Toolkit
- GWT Basic Interactivity
- Google Sitemaps
- Google Sitemaps Resources
- Accessibility
- Web Accessibility
- XML Accessibility
- Accessibility Resources
- The Semantic Web
- Defining a New Ontology
- OWL: Web Ontology Language
- Semantic Web Resources
- Google Base
- Microformats
- StructuredBlogging
- Live Clipboard
- WML
- XHTML-MP
- WML Resources
- Google Web Services
- Google Web Services API
- Google Web Services Resources
- The Yahoo! Web Services Interface
- Yahoo! Web Services and PHP
- Yahoo! Web Services Resources
- eBay REST API
- WordML
- WordML Part 2: Lists
- WordML Part 3: Tables
- WordML Resources
- DocBook
- Articles
- Books and e-Books
- Official Documentation and Implementations
- XML Query
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- XForms
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- Resource Description Framework (RDF)
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- Topic Maps
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation, Implementations, and Other Resources
- Rich Site Summary (RSS)
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- Simple Sharing Extensions (SSE)
- Atom
- Podcasting
- Podcasting Resources
- Scalable Vector Graphics (SVG)
- Informit Articles and Sample Chapters
- Books and e-Books
- Official Documentation
- OPML
- OPML Resources
- Summary
- Projects
- JavaScript TimeTracker: JSON and PHP
- The Javascript Timetracker
- Refactoring to Javascript Objects
- Creating the Yahoo! Widget
- Web Mashup
- Google Maps
- Indeed Mashup
- Mashup Part 3: Putting It All Together
- Additional Resources
- Frequently Asked Questions About XML
- What's XML, and why should I use it?
- What's a well-formed document?
- What's the difference between XML and HTML?
- What's the difference between HTML and XHTML?
- Can I use XML in a browser?
- Should I use elements or attributes for my document?
- What's a namespace?
- Where can I get an XML parser?
- What's the difference between a well-formed document and a valid document?
- What's a validating parser?
- Should I use DOM or SAX for my application?
- How can I stop a SAX parser before it has parsed the entire document?
- 2005 Predictions
- 2006 Predictions
- Nick's Book Picks
The Document Object Model Level 3 Load and Save Recommendation has two main features that don't exist in earlier versions of the DOM:
- The ability to easily create a parser and load a document
- The ability to easily create a writer and output a document
That doesn't sound like much, but it does come with a whole host of other goodies, such as the ability to filter the data as it goes by, control validation, and handle events and errors. So let's take a look at just how this works.
The general idea is that in the earlier versions of the Document Object
Model, everything was defined as an interface, and the actual creation of
a parser (or a Document
for that matter) was left up to the
implementer. That led to a mess of jumbled bindings. DOM Level 3 Load and Save
creates a standard way to create a parser (and an outputter), and throws in a
great deal of control, to boot. Let's start by creating a parser.
import org.w3c.dom.bootstrap.DOMImplementationRegistry; import org.w3c.dom.DOMImplementationList; import org.w3c.dom.ls.DOMImplementationLS; import org.w3c.dom.ls.LSParser; import org.w3c.dom.Document; public class Level3Dom { public static void main (String args[]){ try { System.setProperty(DOMImplementationRegistry.PROPERTY, "org.apache.xerces.dom.DOMImplementationSourceImpl"); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementationLS impl = (DOMImplementationLS)registry.getDOMImplementation("LS"); LSParser builder = impl.createLSParser( DOMImplementationLS.MODE_SYNCHRONOUS, null); Document document = builder.parseURI("http://www.nicholaschase.com/personal.xml"); } catch (Exception e){ System.out.println(e.toString()); } } }
Now, the first part of this class is the creation of a DOM implementation;
this new DOMImplementationRegistry
is part of the DOM Level 3 Core, but
for now understand that it enables you to choose a DOMImplementation
with particular features and characteristics. In this case, we're choosing
an implementation that supports the LS
feature.
Next, we're using the DOMImplementationLS
to create the a synchronous
parser -- in other words, it waits until it's done parsing before allowing the application
to move on -- and, finally, parsing the data to create a Document
object.
Note that
we have three choices for parsing the data:
parse(LSInput input)
: This method takes anLSInput
as an argument. AnLSInput
can represent a public identifier, a system identifier (such as a file name), a byte stream, a URL, or a character stream.parseURI(String url)
: This method takes a relative or absolute URL -- well, to be strictly accurate, a URI -- and parses the information at that location.parseWithContext(LSInput input, Node context, short action)
: This method actually enables you to parse one document into another. Depending on the value of theaction
parameter, the new data may follow, preceed, or even replace existing data.
One of the advantages of using this method of parsing is the ability to control aspects of the parse. For example, you can specify that the document should be validated based on a schema:
... public class Level3Dom { public static void main (String args[]){ try { System.setProperty(DOMImplementationRegistry.PROPERTY, "org.apache.xerces.dom.DOMImplementationSourceImpl"); DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); DOMImplementationLS impl = (DOMImplementationLS)registry.getDOMImplementation("LS"); LSParser builder = impl.createLSParser( DOMImplementationLS.MODE_SYNCHRONOUS, null); DOMConfiguration config = builder.getDomConfig(); config.setParameter("validate", Boolean.TRUE); config.setParameter("schema-type", "http://www.w3.org/2001/XMLSchema"); config.setParameter("schema-location", "http://www.nicholaschase.com/informit/personal.xsd"); Document document = builder.parseURI("http://www.nicholaschase.com/personal.xml"); } catch (Exception e){ System.out.println(e.toString()); } } }
The DOMConfiguration
object is part of the Core, but
for now understand that it enables you to set parameters such as whether
or not to include comments, normalize namespaces, and so on. You can
apply it to a Document
, but the DOMConfiguration
you create for the LSParser
doesn't carry over to the actual
Document
object the parser creates.
You can also filter the data that gets passed through, in a manner similar to the one that first appeared in the DOM Level 2 Traversal Recommendation. First you create a filter class:
import org.w3c.dom.ls.LSParserFilter; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.traversal.NodeFilter; public class InputFilter implements LSParserFilter{ public short acceptNode(Node enode) { return NodeFilter.FILTER_ACCEPT; } public int getWhatToShow() { return NodeFilter.SHOW_ELEMENT; } public short startElement(Element elt) { return LSParserFilter.FILTER_ACCEPT; } }
This filter passes everything through, but you can create your own custom filter that determines what information should and should not be part of your document. You can also use the filter to change the data as it goes by. Once you've created your filter, you can add it to the parser:
... import org.w3c.dom.DOMConfiguration; import org.w3c.dom.ls.LSParserFilter; public class Level3Dom { public static void main (String args[]){ try { ... LSParser builder = impl.createLSParser( DOMImplementationLS.MODE_SYNCHRONOUS, null); DOMConfiguration config = builder.getDomConfig(); config.setParameter("validate", Boolean.TRUE); config.setParameter("schema-type", "http://www.w3.org/2001/XMLSchema"); config.setParameter("schema-location", "http://www.nicholaschase.com/informit/personal.xsd"); LSParserFilter filter = new InputFilter(); builder.setFilter(filter); Document document = builder.parseURI("http://www.nicholaschase.com/personal.xml"); } catch (Exception e){ System.out.println(e.toString()); } } }
You can use a similar method to add an error handler to the parser. First, create the error handler:
import org.w3c.dom.DOMErrorHandler; import org.w3c.dom.DOMError; public class HandleErrors implements DOMErrorHandler { public boolean handleError(DOMError error){ short severity = error.getSeverity(); if (severity == error.SEVERITY_ERROR) { System.out.println("[our-dom3-error]: "+error.getMessage()); } if (severity == error.SEVERITY_WARNING) { System.out.println("[our-dom3-warning]: "+error.getMessage()); } return true; } }
This class, borrowed slightly from the Xerces samples, simply
outputs the message, along with some idea of the severity. Adding
it to the parser is strightforward, using the DOMConfiguration
:
... public class Level3Dom { public static void main (String args[]){ try { ... LSParser builder = impl.createLSParser( DOMImplementationLS.MODE_SYNCHRONOUS, null); DOMConfiguration config = builder.getDomConfig(); ... config.setParameter("error-handler", new HandleErrors()); Document document = builder.parseURI("http://www.nicholaschase.com/personal.xml"); } catch (Exception e){ System.out.println(e.toString()); } } }
OK, so what about output? Output follows the same general mode as input. For example, we can write the document out to a file:
... import org.w3c.dom.ls.LSSerializer; import org.w3c.dom.ls.LSOutput; public class Level3Dom { public static void main (String args[]){ try { ... Document document = builder.parseURI("http://www.nicholaschase.com/personal.xml"); LSSerializer writer = impl.createLSSerializer(); LSOutput output = impl.createLSOutput(); output.setSystemId("file:///personalout.xml"); writer.write(document, output); } catch (Exception e){ System.out.println(e.toString()); } } }
You create the output, specify where the data should go, and then feed the
Document
(or any Node
, actually) to the LSSerializer
with that output, and it's done. Note that here you also have three options:
write(Document document, LSOutput output)
: This method sends the data to the specified location, be it a URL (or URI) or character or byte stream.writeToString(Node node)
: Perhaps the most eagerly awaited new fuction, this method simply serializes aNode
to a string, a function that should have been trivially easy from the start, but wasn't.writeToURI(String uri)
: This method simply outputs the XML to a specified location. It's a convenience method that is the same as usingwrite()
to send the data to anLSOutput
that has thesystemId
property set.
Note that you can use filters and error handlers when you output the data just as you can when you input it. For example, you can specify that you don't want to pass on any comments:
... public class Level3Dom { public static void main (String args[]){ try { ... Document document = builder.parseURI("http://www.nicholaschase.com/personal.xml"); LSSerializer writer = impl.createLSSerializer(); LSOutput output = impl.createLSOutput(); output.setSystemId("file:///personalout.xml"); config = writer.getDomConfig(); config.setParameter("comments", Boolean.FALSE); writer.write(document, output); } catch (Exception e){ System.out.println(e.toString()); } } }
Overall, while it might take a little bit of getting used to, DOM Level 3 Load and Save makes it simpler and easier to load and serielize data.