출처 :
http://www.ociweb.com/mark/programming/WAX.html
삽질 끝????
What's the best way to read a large XML document?
Of course you'd use a SAX parser or a pull parser.
What's the best way to write a large XML document?
Building a DOM structure to describe a large XML document
won't work because it won't fit in memory.
Even if it did, it's not a simple API to use.
There hasn't been a solution that is
simple and memory efficient until now.
Writing API for XML (WAX) is a free, open-source, library
for writing XML documents.
I created it because I got an OutOfMemoryError
while trying to output a large XML document
from an application I wrote using JDOM,
another Java-based XML library.
I searched for other libraries
that could write large XML documents
but couldn't find any that were
as simple to use as I thought they should be.
WAX is released under the
LGPL
with the intention of making its use unencumbered.
It is well-tested and ready for production use.
The WAX home page is at
http://www.ociweb.com/wax/.
Java and Ruby versions are available now.
The Java version of WAX can be downloaded from Google Code at
http://code.google.com/p/waxy/.
For information about the Ruby version, click here.
Ports for other programming languages will follow.
WAX has the following characteristics:
- focuses on writing XML, not reading it
- requires less code than other approaches
- uses less memory than other approaches
(because it outputs XML as each method is called rather than
storing it in a DOM-like structure and outputting it later)
- doesn't depend on any Java classes
other than standard JDK classes
- is a small library (around 16K)
- writes all XML node types
- always outputs well-formed XML or throws an exception
unless running in "trust me" mode
- provides extensive error checking
- automatically escapes special characters in
text and attribute values (unless "unescaped" methods are used)
- allows most error checking to be turned off for performance
- knows how to associate DTDs, XML Schemas and
XSLT stylesheets with the XML it outputs
- is well-suited for writing XML request and response messages
for REST-based and SOAP-based services
This section provides many examples of using WAX.
Each code snippet is followed by the output it produces.
When the no-arg WAX constructor is used,
XML is written to standard output.
There are also WAX constructors that take
a java.io.OutputStream
or a java.io.Writer
object.
Here's a simple example where only a root element is written:
WAX wax = new WAX();
wax.start("car").close();
After a WAX
object is closed,
a new one must be created in order to write more XML.
In the examples that follow, assume that has been done.
Let's write a root element with some text inside:
wax.start("car").text("Prius").end().close();
The default indentation used is two spaces.
The end
method terminates the element
that is started by the start
method.
In this case it's not necessary to call end
because the close
method
terminates all unterminated elements.
Let's put the text inside a child element:
wax.start("car").start("model").text("Prius").close();
<car>
<model>Prius</model>
</car>
Let's do the same with the
child
convenience method:
which is equivalent to calling start
,
text
and end
.
wax.start("car").child("model", "Prius").close();
<car>
<model>Prius</model>
</car>
Let's put text containing all the special XML characters
in a CDATA section:
wax.start("car").start("model").cdata("1<2>3&4'5\";6").close();
<car>
<model>
<![CDATA[1<2>3&4'5"6]]>
</model>
</car>
Let's output the XML without indentation, on a single line:
wax.noIndentsOrLineSeparators();
wax.start("car").child("model", "Prius").close();
<car><model>Prius</model></car>
Let's indent the XML with four spaces
instead of the default of two:
wax.setIndent(" ");
wax.start("car").child("model", "Prius").close();
<car>
<model>Prius</model>
</car>
Let's add an attribute:
wax.start("car").attr("year", 2008).child("model", "Prius").close();
<car year="2008">
<model>Prius</model>
</car>
Attributes must be specified before
any content for their element is specified.
For example, calling
start
, attr
and text
is valid,
but calling
start
, text
and attr
is not.
If this rule is violated then
an IllegalStateException
is thrown.
Let's add an XML declaration:
WAX wax = new WAX(Version.V1_0);
wax.start("car").attr("year", 2008)
.child("model", "Prius").close();
<?xml version="1.0" encoding="UTF-8"?>
<car year="2008">
<model>Prius</model>
</car>
Let's add a comment:
wax.comment("This is a hybrid car.")
.start("car").child("model", "Prius").close();
<!-- This is a hybrid car. -->
<car>
<model>Prius</model>
</car>
Let's add a processing instruction:
wax.processingInstruction("target", "data")
.start("car").attr("year", 2008)
.child("model", "Prius").close();
<?target data?>
<car year="2008">
<model>Prius</model>
</car>
Let's associate an XSLT stylesheet with the XML:
The xslt
method is a convenience method for adding
this commonly used processing instruction.
wax.xslt("car.xslt")
.start("car").attr("year", 2008)
.child("model", "Prius").close();
<?xml-stylesheet type="text/xsl" href="car.xslt"?>
<car year="2008">
<model>Prius</model>
</car>
Let's associate a default namespace with the XML:
wax.start("car").attr("year", 2008)
.defaultNamespace("http://www.ociweb.com/cars")
.child("model", "Prius").close();
<car year="2008"
xmlns="http://www.ociweb.com/cars">
<model>Prius</model>
</car>
Let's associate a non-default namespace with the XML:
String prefix = "c";
wax.start(prefix, "car").attr("year", 2008)
.namespace(prefix, "http://www.ociweb.com/cars")
.child(prefix, "model", "Prius").close();
<c:car year="2008"
xmlns:c="http://www.ociweb.com/cars">
<c:model>Prius</c:model>
</c:car>
Like attributes, namespaces must be specified
before any content for their element is specified.
If this rule is violated then
an IllegalStateException
is thrown.
Let's associate an XML Schema with the XML:
wax.start("car").attr("year", 2008)
.defaultNamespace("http://www.ociweb.com/cars", "car.xsd")
.child("model", "Prius").close();
<car year="2008"
xmlns="http://www.ociweb.com/cars"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xsi:schemaLocation="http://www.ociweb.com/cars car.xsd">
<model>Prius</model>
</car>
Let's associate multiple XML Schemas with the XML:
wax.start("car").attr("year", 2008)
.defaultNamespace("http://www.ociweb.com/cars", "car.xsd")
.namespace("m", "http://www.ociweb.com/model", "model.xsd")
.child("m", "model", "Prius").close();
<car year="2008"
xmlns="http://www.ociweb.com/cars"
xmlns:m="http://www.ociweb.com/model"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xsi:schemaLocation="http://www.ociweb.com/cars car.xsd
http://www.ociweb.com/model model.xsd">
<m:model>Prius</m:model>
</car>
Let's associate a DTD with the XML:
wax.dtd("car.dtd")
.start("car").attr("year", 2008)
.child("model", "Prius").close();
<!DOCTYPE car SYSTEM "car.dtd">
<car year="2008">
<model>Prius</model>
</car>
Let's add and use entity definitions:
String url = "http://www.ociweb.com/xml/";
wax.entityDef("oci", "Object Computing, Inc.")
.externalEntityDef("moreData", url + "moreData.xml")
.start("root")
.unescapedText("The author works at &oci; in St. Louis, Missouri.",
true)
.unescapedText("&moreData;", true)
.close();
<!DOCTYPE root [
<!ENTITY oci "Object Computing, Inc.">
<!ENTITY moreData SYSTEM "http://www.ociweb.com/xml/moreData.xml">
]>
<root>
The author works at &oci; in St. Louis, Missouri.
&moreData;
</root>
A common usage pattern is to pass a
WAX
object to a method of model objects
that use it to write their XML representation.
For example, a Car
class could have the following method.
public void toXML(WAX wax) {
wax.start("car")
.attr("year", year)
.child("make", make)
.child("model", model)
.end();
}
An example of the XML this would produce follows:
<car year="2008">
<make>Toyota</make>
<model>Prius</model>
</car>
A Person
class whose objects hold a reference to
an Address
object could have the following method.
public void toXML(WAX wax) {
wax.start("person")
.attr("birthdate", birthdate)
.child("name", name);
address.toXML(wax);
wax.end();
}
The Address
class could have the following method.
public void toXML(WAX wax) {
wax.start("address")
.child("street", street);
.child("city", city);
.child("state", state);
.child("zip", zip);
.end();
}
An example of the XML this would produce follows:
<person birthdate="4/16/1961">
<name>R. Mark Volkmann</name>
<address>
<street>123 Some Street</street>
<city>Some City</city>
<state>MO</state>
<zip>12345</zip>
</address>
</person>