java 解析 xml 的工具类是多样的,
这里采用 sun 公司的 jaxp 解析 xml 文档,
代码及结果详见全文,欢迎各位给出其它的解析工具类,以便比较优劣。
jaxp download from http://java.sun.com/xml.
build.xml
<?xml version="1.0" ?>
<project name="lushaojie_project" default="execute" >
<description>Compiles and runs a simple program</description>
<target name="init">
<mkdir dir="classes" />
</target>
<target name="compile" depends="init"
description="Compiles the source code">
<javac
srcdir="src"
destdir="classes"
/>
</target>
<target name="execute" depends="compile"
description="Runs the program">
<echo level="warning" message="running" />
<java
classname="DOMEcho"
classpath="classes">
<arg value="res/namespace.xml"/>
</java>
</target>
</project>
DOMEcho.java
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Crimson" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, Sun Microsystems, Inc.,
* http://www.sun.com. For more information on the Apache Software
* Foundation, please see <http://www.apache.org/>.
*/
// JAXP packages
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import org.w3c.dom.*;
import java.io.*;
/**
* Program to echo a DOM tree using DOM Level 2 interfaces. Use JAXP to
* read in and create a DOM tree. DOM currently does not provide a method
* to do this. (This is planned for Level 3.) See the method main for the
* three basic steps. Once the application obtains a DOM Document tree, it
* dumps out the nodes in the tree and associated node attributes for each
* node.
*
* Notes: Program flags may be used to create possibly non-conformant (but
* useful) DOM trees. Program also shows an example of using an
* ErrorHandler.
*
* @author Edwin Goei <edwingo@apache.org>
*/
public class DOMEcho {
/** All output will be use this encoding */
static final String outputEncoding = "UTF-8";
/** Output goes here */
private PrintWriter out;
/** Indent level */
private int indent = 0;
/** Indentation will be in multiples of basicIndent */
private final String basicIndent = " ";
DOMEcho(PrintWriter out) {
this.out = out;
}
/**
* Echo common attributes of a DOM2 Node and terminate output with an
* EOL character.
*/
private void printlnCommon(Node n) {
out.print(" nodeName=\"" + n.getNodeName() + "\"");
String val = n.getNamespaceURI();
if (val != null) {
out.print(" uri=\"" + val + "\"");
}
val = n.getPrefix();
if (val != null) {
out.print(" pre=\"" + val + "\"");
}
val = n.getLocalName();
if (val != null) {
out.print(" local=\"" + val + "\"");
}
val = n.getNodeValue();
if (val != null) {
out.print(" nodeValue=");
if (val.trim().equals("")) {
// Whitespace
out.print("[WS]");
} else {
out.print("\"" + n.getNodeValue() + "\"");
}
}
out.println();
}
/**
* Indent to the current level in multiples of basicIndent
*/
private void outputIndentation() {
for (int i = 0; i < indent; i++) {
out.print(basicIndent);
}
}
/**
* Recursive routine to print out DOM tree nodes
*/
private void echo(Node n) {
// Indent to the current level before printing anything
outputIndentation();
int type = n.getNodeType();
switch (type) {
case Node.ATTRIBUTE_NODE:
out.print("ATTR:");
printlnCommon(n);
break;
case Node.CDATA_SECTION_NODE:
out.print("CDATA:");
printlnCommon(n);
break;
case Node.COMMENT_NODE:
out.print("COMM:");
printlnCommon(n);
break;
case Node.DOCUMENT_FRAGMENT_NODE:
out.print("DOC_FRAG:");
printlnCommon(n);
break;
case Node.DOCUMENT_NODE:
out.print("DOC:");
printlnCommon(n);
break;
case Node.DOCUMENT_TYPE_NODE:
out.print("DOC_TYPE:");
printlnCommon(n);
// Print entities if any
NamedNodeMap nodeMap = ((DocumentType)n).getEntities();
indent += 2;
for (int i = 0; i < nodeMap.getLength(); i++) {
Entity entity = (Entity)nodeMap.item(i);
echo(entity);
}
indent -= 2;
break;
case Node.ELEMENT_NODE:
out.print("ELEM:");
printlnCommon(n);
// Print attributes if any. Note: element attributes are not
// children of ELEMENT_NODEs but are properties of their
// associated ELEMENT_NODE. For this reason, they are printed
// with 2x the indent level to indicate this.
NamedNodeMap atts = n.getAttributes();
indent += 2;
for (int i = 0; i < atts.getLength(); i++) {
Node att = atts.item(i);
echo(att);
}
indent -= 2;
break;
case Node.ENTITY_NODE:
out.print("ENT:");
printlnCommon(n);
break;
case Node.ENTITY_REFERENCE_NODE:
out.print("ENT_REF:");
printlnCommon(n);
break;
case Node.NOTATION_NODE:
out.print("NOTATION:");
printlnCommon(n);
break;
case Node.PROCESSING_INSTRUCTION_NODE:
out.print("PROC_INST:");
printlnCommon(n);
break;
case Node.TEXT_NODE:
out.print("TEXT:");
printlnCommon(n);
break;
default:
out.print("UNSUPPORTED NODE: " + type);
printlnCommon(n);
break;
}
// Print children if any
indent++;
for (Node child = n.getFirstChild(); child != null;
child = child.getNextSibling()) {
echo(child);
}
indent--;
}
private static void usage() {
System.err.println("Usage: DOMEcho [-opts] <filename>");
System.err.println(" -v = validation");
System.err.println(" -ws = do not create whitespace nodes");
System.err.println(" -co[mments] = do not create comment nodes");
System.err.println(" -cd[ata] = put CDATA into Text nodes");
System.err.println(" -e[ntity-ref] = create EntityReference nodes");
System.exit(1);
}
public static void main(String[] args) throws Exception {
String filename = null;
boolean validation = false;
boolean ignoreWhitespace = false;
boolean ignoreComments = false;
boolean putCDATAIntoText = false;
boolean createEntityRefs = false;
for (int i = 0; i < args.length; i++) {
if (args[i].equals("-v")) {
validation = true;
} else if (args[i].equals("-ws")) {
ignoreWhitespace = true;
} else if (args[i].startsWith("-co")) {
ignoreComments = true;
} else if (args[i].startsWith("-cd")) {
putCDATAIntoText = true;
} else if (args[i].startsWith("-e")) {
createEntityRefs = true;
} else {
filename = args[i];
// Must be last arg
if (i != args.length - 1) {
usage();
}
}
}
if (filename == null) {
usage();
}
// Step 1: create a DocumentBuilderFactory and configure it
DocumentBuilderFactory dbf =
DocumentBuilderFactory.newInstance();
// Optional: set various configuration options
dbf.setValidating(validation);
dbf.setIgnoringComments(ignoreComments);
dbf.setIgnoringElementContentWhitespace(ignoreWhitespace);
dbf.setCoalescing(putCDATAIntoText);
// The opposite of creating entity ref nodes is expanding them inline
dbf.setExpandEntityReferences(!createEntityRefs);
// At this point the DocumentBuilderFactory instance can be saved
// and reused to create any number of DocumentBuilder instances
// with the same configuration options.
// Step 2: create a DocumentBuilder that satisfies the constraints
// specified by the DocumentBuilderFactory
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException pce) {
System.err.println(pce);
System.exit(1);
}
// Set an ErrorHandler before parsing
OutputStreamWriter errorWriter =
new OutputStreamWriter(System.err, outputEncoding);
db.setErrorHandler(
new MyErrorHandler(new PrintWriter(errorWriter, true)));
// Step 3: parse the input file
Document doc = null;
try {
doc = db.parse(new File(filename));
} catch (SAXException se) {
System.err.println(se.getMessage());
System.exit(1);
} catch (IOException ioe) {
System.err.println(ioe);
System.exit(1);
}
// Print out the DOM tree
OutputStreamWriter outWriter =
new OutputStreamWriter(System.out, outputEncoding);
new DOMEcho(new PrintWriter(outWriter, true)).echo(doc);
}
// Error handler to report errors and warnings
private static class MyErrorHandler implements ErrorHandler {
/** Error handler output goes here */
private PrintWriter out;
MyErrorHandler(PrintWriter out) {
this.out = out;
}
/**
* Returns a string describing parse exception details
*/
private String getParseExceptionInfo(SAXParseException spe) {
String systemId = spe.getSystemId();
if (systemId == null) {
systemId = "null";
}
String info = "URI=" + systemId +
" Line=" + spe.getLineNumber() +
": " + spe.getMessage();
return info;
}
// The following methods are standard SAX ErrorHandler methods.
// See SAX documentation for more info.
public void warning(SAXParseException spe) throws SAXException {
out.println("Warning: " + getParseExceptionInfo(spe));
}
public void error(SAXParseException spe) throws SAXException {
String message = "Error: " + getParseExceptionInfo(spe);
throw new SAXException(message);
}
public void fatalError(SAXParseException spe) throws SAXException {
String message = "Fatal Error: " + getParseExceptionInfo(spe);
throw new SAXException(message);
}
}
}
namespace.xml
<?xml version="1.0" encoding="us-ascii"?>
<examples>
<section xmlns='http://www.example.com/books-r-us'>
<title>Book-Signing Event</title>
<signing>
<author title="Mr." name="Vikram Seth"/>
<book title="A Suitable Boy" price="95" />
</signing>
</section>
<reservation xmlns:html="http://www.w3.org/TR/REC-html40">
<name html:class="largeSansSerif">Seth, Vikram</name>
<seat class="Y" html:class="largeMonotype">33B</seat>
<html:a href='/servlets/ResStatus'>Check Status</html:a>
<departure>1997-05-24T19:22:00+5</departure>
</reservation>
</examples>
D:\test>ant
Buildfile: build.xml
init:
[mkdir] Created dir: D:\test\classes
compile:
[javac] Compiling 1 source file to D:\test\classes
execute:
[echo] running
[java] DOC: nodeName="#document"
[java] ELEM: nodeName="examples"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="section"
[java] ATTR: nodeName="xmlns" nodeValue="http://www.example.com/boo
ks-r-us"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="title"
[java] TEXT: nodeName="#text" nodeValue="Book-Signing Event"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="signing"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="author"
[java] ATTR: nodeName="title" nodeValue="Mr."
[java] ATTR: nodeName="name" nodeValue="Vikram Seth"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="book"
[java] ATTR: nodeName="title" nodeValue="A Suitable Boy"
[java] ATTR: nodeName="price" nodeValue="95"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="reservation"
[java] ATTR: nodeName="xmlns:html" nodeValue="http://www.w3.org/TR/
REC-html40"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="name"
[java] ATTR: nodeName="html:class" nodeValue="largeSansSerif"
[java] TEXT: nodeName="#text" nodeValue="Seth, Vikram"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="seat"
[java] ATTR: nodeName="class" nodeValue="Y"
[java] ATTR: nodeName="html:class" nodeValue="largeMonotype"
[java] TEXT: nodeName="#text" nodeValue="33B"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="html:a"
[java] ATTR: nodeName="href" nodeValue="/servlets/ResStatus"
[java] TEXT: nodeName="#text" nodeValue="Check Status"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] ELEM: nodeName="departure"
[java] TEXT: nodeName="#text" nodeValue="1997-05-24T19:22:00+5"
[java] TEXT: nodeName="#text" nodeValue=[WS]
[java] TEXT: nodeName="#text" nodeValue=[WS]
BUILD SUCCESSFUL
Total time: 5 seconds