<?xml version='1.0' encoding='UTF-8'?>
<?xml-stylesheet type="text/xsl" href="../documentation/documentation.xsl"?>
<!DOCTYPE documentation SYSTEM "../documentation/documentation.dtd">
<documentation> 
	<head> 
		<title>REXML</title>
		<banner href="img/rexml.png"/>
		<version>2.0.1</version> 
		<date>*2002-081</date>
		<home>http://www.germane-software.com/software/rexml</home>
		<base>rexml</base>
		<archive type="unix">Current release</archive> 
		<archive type="dos">Current release</archive>
		<language>ruby</language>
		<author email="ser@germane-software.com" jabber="ser@jabber.com" href="http://www.germane-software.com/~ser">Sean Russell</author>
	</head>


	<overview> 
		<purpose lang="en"> 
			<p>REXML is an XML processor for the language Ruby.  REXML is conformant
				(passes 100% of the Oasis non-validating tests), and includes full
				XPath support.  It is reasonably fast, and is implemented in pure
				Ruby.  Best of all, it has a clean, intuitive API.</p>
			<p>This software is distribute under the <link
					href="LICENSE.txt">Ruby license</link>.</p>
	</purpose> 


	<general> 
		<p>Why REXML? There, at the time of this writing, already two XML
			parsers for Ruby. The first is a Ruby binding to a native XML
			parser. This is a fast parser, using proven technology. However,
			it isn&#39;t very portable. The second is a native Ruby
			implementation, and as useful as it is, it has (IMO) a difficult
			API.</p>
		<p>I have this problem: I dislike obscifucated APIs. There are
			several XML parser APIs for Java. Most of them follow DOM or SAX,
			and are very similar in philosophy with an increasing number of
			Java APIs. Namely, they look like they were designed by theorists
			who never had to use their own APIs. The extant XML APIs, in
			general, suck. They take a markup language which was specifically
			designed to be very simple, elegant, and powerful, and wrap an
			obnoxious, bloated, and large API around it. I was always having
			to refer to the API documentation to do even the most basic XML
			tree manipulations; nothing was intuitive, and almost every
			operation was complex. </p>
		<p>Then along came Electric XML. </p> 
		<p>Ah, bliss. Look at the Electric XML API. First, the library is
			small; less that 500K. Next, the API is intuitive. You want to
			parse a document? doc = new Document( some_file ). Create and add
			a new element? element = parent.addElement( tag_name ). Write out
			a subtree?? element.write( writer ). Now how about DOM? To parse
			some file: parser = new DOMParser(); parser.parse( new
			InputSource( new FileInputStream( some_file ) ) ). Create a new
			element? First you have to know the owning document of the
			to-be-created node (can anyone say &#34;global variables, or
			obtuse, multi-argument methods&#34;?) and call element =
			doc.createElement( tag_name ). Then you get to call
			parent.appendChild( element ). &#34;appendChild&#34;? Where did
			they get that from? How many different methods do we have in Java
			in how many different classes for adding children to parents?
			addElement()? add()? put()? appendChild()? Heaven forbid that you
			want to create an Element elsewhere in the code without having
			access to the owning document. I&#39;m not even going to go into
			what travesty of code you have to go through to write out an XML
			sub-tree in DOM. </p>
		<p>So, I use Electric XML extensively. It is small, fast, and
			intuitive. IE, the API doesn&#39;t add a bunch of work to the task
			of writing software. When I started to write more software in
			Ruby, I needed an XML parser. I wasn&#39;t keen on the native
			library binding, &#34;XMLParser&#34;, because I try to avoid
			complex library dependancies in my software, when I can. For a
			long time, I used NQXML, because it was the only other parser out
			there. However, the NQXML API can be even more painful than the
			Java DOM API. Almost all element operations requires accessing
			some indirect node access... you had to do something like
			element.node.attr[&#39;key&#39;], and it is never obvious to me
			when you access the element directly, or the node.. or, really,
			why they&#39;re two different objects, anyway. This is even more
			unfortunate since Ruby is so elegent and intuitive, and bad APIs
			really stand out.  I'm not, by the way, trying to insult NQXML; I
			just don't like the API.</p>
		<p>I wrote the people at TheMind (Electric XML... get it?) and asked
			them if I could do a translation to Ruby. They said yes. After a
			few weeks of hacking on it for a couple of hours each week, and
			after having gone down a few blind alleys in the translation, I
			had a working beta. IE, it parsed, but hadn&#39;t gone through a
			lot of strenuous testing. Along the way, I had made a few changes
			to the API, and a lot of changes to the code. First off, Ruby does
			iterators differently than Java. Java uses a lot of helper
			classes. Helper classes are exactly the kinds of things that
			theorists come up with... they look good on paper, but using them
			is like chewing glass. You find that you spend 50% of your time
			writing helper classes just to support the other 50% of the code
			that actually does the job you were trying to solve in the first
			place. In this case, the Java helper classes are either
			Enumerations or Iterators.  Ruby, on the other hand, uses blocks,
			which is much more elegant. Rather than:</p>
<example>for (Enumeration e=parent.getChildren(); e.hasMoreElements(); ) {
   Element child = (Element)e.nextElement();
   // Do something with child
}</example><p>you get:</p>
<example>parent.each_child{ |child| # Do something with child }</example>
		<p>Can&#39;t you feel the peace and contentment in this block of
		code? Ruby is the language Buddha would have programmed in.</p>
		<p>Anyhoo, I chose to use blocks in REXML directly, since this is
		more common to Ruby code than <code>for x in y ... end</code>, which
		is as orthoganal to the original Java as possible.</p>
		<p>Also, I changed the naming conventions to more Ruby-esque method
		names. For example, the Java method <code>getAttributeValue()</code>
		becomes in Ruby <code>get_attribute_value()</code>. This is a
		toss-up. I actually like the Java naming convention more, but the
		latter is more common in Ruby code, and I&#39;m trying to make things
		easy for Ruby programmers, not Java programmers.</p>
		<p>The biggest change was in the code. The Java version of Electric
		XML did a lot of efficient String-array parsing, character by
		character. Ruby, however, has ubiquitous, efficient, and powerful
		regular expression support. All regex functions are done in native
		code, so it is very fast, and the power of Ruby regex rivals that of
		Perl. Therefore, a direct conversion of the Java code to Ruby would
		have been more difficult, and much slower, than using Ruby regexps. I
		therefore used regexs. In doing so, I cut the number of lines of
		sourcecode by half<footnote>It might interest you to know that at
		last count, Electric XML had ~3,700 non-comment, non-empty lines of
		code.  REXML had ~1,550. This illustrates the marvelous efficiency
		and power of Ruby.</footnote>.</p>
		<p>Finally, by this point the API looks almost nothing like the
		original Electric XML API, and practically none of the code is even
		vaguely similar.  However, even though the actual code is completely
		different, I did borrow the same process of processing XML as
		Electric, and am deeply indebted to the Electric XML code for
		inspiration.</p>
		<p>One last thing.  If you use this software, and you like this
			software, and you feel compelled to make some contribution to the
			author by way of saying "thanks", and you happen to know what a tea
			cozy is and where to get them, then you can send me one.  Send those
			puppies to:<pre>Sean Russell
60252 Rimfire Rd.
Bend, OR  97702
USA</pre>
			If you're outside of the US, make sure you write "gift" on it to
			avoid the taxes.  If you don't want to send a tea cozy, you can
			also send money.  Or don't send anything. Offer me a job I can't
			refuse, in Western Europe somewhere.</p> 
		</general>

		<features lang="en">
			<item>Simple API</item>
			<item>Both stream (SAX) and tree (DOM) parsing<footnote>Be aware,
					however, that REXML is not DOM nor SAX compliant, and will never
					be.  The DOM and SAX APIs are unwieldy.</footnote></item>
			<item>Small</item>
			<item>Native Ruby</item>
			<item>Documentation(!)</item>
		</features>
	</overview>

	<operation lang="en">
		<subsection title="Installation">
			<p>Run &#39;ruby install.rb&#39;.  By the way, you really should
			look at these sorts of files before you run them as root.  They
			could contain anything, and since (in Ruby, at least) they tend to
			be mercifully short, it doesn't hurt to glance over them.  If you
			want to uninstall REXML, run <code>ruby install.rb -u</code>.</p>
		</subsection>

		<subsection title="General Usage">
			<p>Please see <link href="docs/tutorial.html">the Tutorial</link></p>
			<p>The API documentation is <link
			href="doc/index.html">here</link>.  Some examples using
			REXML are included in the distribution archive, and the Tutorial
			provides examples with commentary.</p>
		</subsection>
	</operation>

	<status>
		<subsection title="Change Log">
			<p>2.0.1:  Added some unit tests, and fixed a namespace XPath bug
				WRT attribute default NS's.  Unicode support was screwing up the
				upper end of ASCII support; chars between 0xF0 and 0xFD were getting
				munged.  This has been fixed, at the cost of a small amount of speed.
				Optimized the descendant axes of XPath; it should be significantly
				faster for '//' and other descendant operations.  Added several user
				contributed unit tests.  Re-added QuickPath, the old, non-fully-XPath
				compliant, yet much faster, XPath processor.  Everything is being
				converted to UTF8 now, and the XML declaration reflects this.  See
				the bugs for more information.</p>
			<p>2.0:  True XPath support.  Finally.  XPath is fully implemented now, and
				passes all of the tests I can throw at it, including complex XPaths
				such as 
				<code>'*[* and not(*/node()) and not(*[not(@style)]) and not(*/@style
					!= */@style)]'</code>.  It may be slower than it was, but it should
				be reasonably efficient for what it is doing.  The XPath spec doesn't
				help, and thwarts most attempts at optimization.
				Please see the notes on XPath for more information.  Oh, and some
				minor bugs were fixed in the XML parser.</p>
			<p>1.2.8: Fixed a bug pointed out by Peter Verhage where the element
				names weren't being properly parsed if a namespace was involved.
			</p>
			<p>1.2.7: Fixing problems with the 1.2.6 distribution :-/.  Added an
				"applications using REXML" section in this document -- send me those
				links!  Added rdoc documentation.  I'm not using API2XML anymore.
				I think API2XML was the right model, generating XML rather than HTML
				(which is what rdoc does), but rdoc does a much better job at parsing
				Ruby source, and I really didn't want to go there in the first place.
				Also, I had forgotten to generate the Tutorial HTML.</p>
			<p>1.2.6: Documentation fix (TR). Fixed a bug in Element.add (and,
				therefore, Element.add_element).  Added Robert Feldt's terse
				xml constructor to contrib/ (check it out; it's handy). Tobias
				discovered a terrible bug, whereby ENTITY wasn't printing out a
				final '>'.  After a long discussion with a couple of users, and
				some review of the XML spec, I decided to reverse the default
				handling of whitespace and pretty printing.  REXML now no longer
				defaults to pretty printing, and preserves whitespace unless
				otherwise directed.  Added provisional namespace support to XPath.
				XPath is going to require another rewrite.</p>
			<p>1.2.5: Bug fixes: doctypes that had spaces between the closing ]
				and &gt; generated errors.  There was a small bug that caused too
				many newlines to be generated in some output.  Eelis van der Weegen
				(what a great name!) pointed out one of the numerous API errors.
				Julian requested that add_attributes take both Hash (original) and
				array of arrays (as produced by StreamListener).  I killed the
				mailing list, accidentally, and fixed it again.  Fixed a bug in
				next_sibling, caused by a combination of mixing overriding
				&lt;=&gt;() and using Array.index().</p>
			<p>1.2.4: Changes since 1.1b: 100% OASIS valid tests passed.
				UTF-8/16 support.  Many bug fixes. to_a() added to Parent and
				Element.elements.  Updated tutorial.  Added variable IOSource
				buffer size, for stream parsing.  delete() now fails silently
				rather than throwing an exception if it can't find the elemnt to
				delete.  Added a patch to support REXMLBuilder. Reorganized file
				layout in distribution; added a repackaging program; added the
				logo.</p>
			<p>1.1b: Changes since 1.1a: Stream parsing added. Bug fixes in entity 
				parsing.  New XPath implementation, fixing many bugs and making
				feature complete.  Completed whitespace handling, adding much
				functionality and fixing several bugs.  Added convenience methods
				for inserting elememnts.  Improved error reporting.  Fixed
				attribute content to correctly handle quotes and apostrophes. Added
				mechanisms for handling raw text.  Cleaned up utility programs
				(profile.rb, comparison.rb, etc.).  Improved speed a little.
				Brought REXML up to 98.9% OASIS valid source compliance.</p>
		</subsection>
		<subsection title="Speed and Completeness">
			<p>Unfortunately, NQXML is the only package REXML can be compared
				against; XMLParser uses expat, which is a native library, and
				really is a different beast altogether.  So in comparing NQXML and
				REXML you can look at three things: speed, size, and API.</p>
			<p><link href="benchmarks/index.html">Benchmarks</link></p>
			<p>REXML is faster than NQXML in some things, and 
				slower than NQXML in a couple of things.  You can see this for
				yourself by running the supplied benchmarks, although it may not
				be clear what operations are slower from these.  Most of the
				places where REXML are slower are because of the convenience
				methods<footnote>For example, <code>element.elements[index]</code> 
					isn't
				really an array operation; index can be an Integer or an XPath,
				and this feature is relatively time expensive.</footnote>.  On the 
				positive side,
				most of the convenience methods can be bypassed if you know what
				you are doing.  Check the <link href="benchmarks/index.html">
				benchmark comparison page</link> for a <em>general</em>
				comparison.  You can look at the benchmark code yourself to decide
				how much salt to take with them.</p>
			<p>The sizes of the XML parsers are close<footnote>As measured with 
					<code>ruby -nle 'print unless /^\s*(#.*|)$/' *.rb | wc -l</code>
				</footnote>.  NQXML 1.1.3 has 1580 non-blank, non-comment lines of
				code; REXML 2.0 has 2340<footnote>REXML started out with about
					1200, but that number has been steadily increasing as features
					are added.  XPath accounts for 541 lines of that code, so the core
					REXML has about 1800 LOC.</footnote>.</p>
			<p>The last thing is the API, and this is where I think REXML wins.
				The core API is clean and intuitive, and things
				work the way you would expect them to.  Convenience methods
				abound, and you can code for either convenience or speed.
				REXML code is terse, and readable, like Ruby code should be.
				The best way to decide which you like more is to write a couple
				of small applications in each, then use the one you're more
				comfortable with.</p>
			<p>It should be noted that NQXML does not support XPath.</p>
		</subsection>


		<subsection title="XPath">
			<p>As of release 2.0, XPath 1.0 is fully implemented.</p>
			<p>I fully expect bugs to crop up from time to time, so if you see any 
				bogus XPath results, please let me know.  That said, since I'm 
				now following the XPath grammar and spec fairly closely, I suspect that 
				you won't be surprised by REXML's XPath very often, and it should become 
				rock solid fairly quickly.</p>
			<p>Check the "bugs" section for known problems; there are little bits of
				XPath here and there that are not yet implemented, but I'll get to
				them soon.</p>
			<p>Namespace support is rather odd, but it isn't my fault.  I can
				only do so much and still conform to the specs.  In particular,
				XPath attempts to help as much as possible.  Therefore, in the trivial
				cases, you can pass namespace prefixes to Element.elements[...] and
				so on -- in these cases, XPath will use the namespace environment
				of the base element you're starting your XPath search from.  However,
				if you want to do something more complex, like pass in your own
				namespace environment, you have to use the XPath first(), each(),
				and match() methods.  Also, default namespaces <em>force</em> you
				to use the XPath methods, rather than the convenience methods, 
				because there is no way for XPath to know what the mappings for
				the default namespaces should be.  This is exactly why I loath
				namespaces -- a pox on the person(s) who thought them up!</p>
		</subsection>


		<subsection title="Namespaces">
			<p>Namespace support is now fairly stable.  One thing to be aware
			of is that REXML is not (yet) a validating parser.  This means
			that some invalid namespace declarations are not caught.</p>
			<p>Namespace support in XPath works (provisionally).</p>
		</subsection>

		<subsection title="Mailing list">
			<p> There is a low-volume mailing list dedicated to REXML.  To subscribe,
				send an empty email to <link href="mailto:ser-rexml-subscribe@germane-software.com">ser-rexml-subscribe@germane-software.com</link>.
					This list is more or less spam proof.  To unsubscribe, similarly send
					a message to <link href="mailto:ser-rexml-unsubscribe@germane-software.com">ser-rexml-unsubscribe@germane-software.com</link>.</p>
		</subsection>

		<subsection title="Applications that use REXML">
			<list>
				<item>Chris Morris' <link href="http://clabs.org/clxmlserial.htm">XML
						Serializer</link>.  XML Serializer provides a serialization mechanism
					for Ruby that provides a bidirectional mapping between Ruby classes
					and XML documents.</item>
				<item>Much of the <link href="http://www.rubyxml.com">RubyXML</link> is
					generated with scripts that use REXML.  RubyXML is a great site for
					information about Ruby and XML.</item>
				<item><link href="http://www.pinkjuice.com/ruby/jelly/">Jelly</link>
					is a generic utility for generating Ruby libs (XML writers) from W3C
					XML schemas.  </item>
			</list>
		</subsection>

		<faq>
			<q>Why is Element.elements indexed off of '1' instead of '0'?</q>
			<a>Because of XPath.  The XPath specification states that the index of
				the first child node is '1'.  Although it may be counter-intuitive to
				base elements on 1, it is more undesireable to have
				element.elements[0] == element.elements[ 'node()[1]' ].  Since I can't
				change the XPath specification, the result is that Element.elements[1]
				is the first child element.</a>
			<q>Why isn't REXML a validating parser?</q>
			<a>Because validating parsers must include code that parses and
				interprets DTDs.  I hate DTDs.  REXML supports the barest minimum
				of DTD parsing, and even that isn't complete.  There is DTD parsing
				code in the works, but I only work on it when I'm really, really
				bored.  Rumor has it that a contributor is working on a DTD parser for
				REXML; rest assured that any such contribution will be included with
				REXML as soon as it is available.</a>
		</faq>

		<bugs lang="en">
			<p>Please send me bug reports.  If you really want your bug fixed fast,
				include an runit method (or methods) that illustrates the problem.
				You don't have to send me an entire suite; all bug submissions go
				into test/contrib_test.rb.  If you don't send me a unit test,
				I'll have to write one myself, which will mean that your bug will take
				significantly longer to fix.</p>
			<p>When submitting bug reports, please include the version of Ruby and
				of REXML that you're using, and the operating system you're running
				on.  Just run:  
				<code>ruby -vrrexml/rexml -e 'p REXML::Version,PLATFORM'</code>
				and paste the results in your bug report.</p>
			<item>Although you may put in ISO-8859-1, <em>you'll get UTF-8 out!!</em>
				This isn't a new bug; I just never noticed it before.  This won't
				affect you if your sources are 7-bit ASCII, but if your document
				contains any characters over 0x80, they'll be converted to UTF-8.
				Within a release or two, I'll try to respect encodings, and spew
				out what gets put in.  For now, you'll have to live with it; this
				is the price of Unicode support.
			</item>
			<item>Any functions that don't work are also bugs... please report them
				to me.</item>
			<item>Parenthetical phrasing (grouping) in XPath is not currently 
				implemented.  This is only because I'm lazy; It'll be in the 2.1 or
				2.2 release.</item>
			<item>The XPath axes "following" and "preceding" do not work.  Don't
				even bother trying.  They will, soon.  "following-sibling" and 
				"preceding-sibling" <em>do</em> work, however.</item>
			<item>Some of the XPath <em>functions</em> are untested, or
				unimplemented.  Let me know if you find any bugs, and I'll fix them
				eventually.  If you send me a unit test (runit, for now) that
				illustrates the problem, I'll try to fix the problem within a couple
				of days (if I can) and send you a patch, personally.
				</item>
			<item status="fixed">Argh!  Namespaces in XPath rears its ugly head, once again!
				Curse XPath!  Curse it!  Even with a real XPath parser,
				namespaces are going to be a pain to deal with.  To make 
				namespaces (which I've always hated) bearable, I'm going to have
				to do some trickery with the non-explicit XPath functions.</item>
			<item status="fixed">Tobias has once again done the unmentionable, and completely
				overturned my comfortable little world.  In this case, he's shown
				XPath to be broken, in a way I hadn't anticipated.  He's got an
				XPath that does some really gnarly things, from an evaluation point
				of view, such as having predicates containing functions which
				themselves have arguments defined by xpaths containing predicates
				and functions.  This is going to take some work.</item>
			<item>There may be a problem with over-escaping characters in
				attribute values.</item>
			<item>Sometimes the test suite hangs or segfaults the Ruby
				interpreter.  If this is something that I can fix, then it is a
				bug, and I will fix it.</item>
		</bugs>

		<todo lang="en">
			<item>Ruby's Regexp pattern '\w' doesn't like non-ASCII characters,
				except for Unicode, which you can force by hand.  I'm getting
				increasing reports about REXML breaking when it encounters characters
				with Umlauts and other things.  I've made it a priority to try
				and fix this, although it'd be better if this sort of thing was
				fixed within Ruby itself.</item>
			<item>With all of the added feature requests, REXML is losing its
				edge.  It is time to go back and profile and speed optimize REXML
				again.</item>
			<item>RFC/RCR on the REXML page</item>
			<item>Add a default listener that constructs trees based on an
				event map.  NQMXML does something like this:<code><![CDATA[
nd = NQXML::Dispatcher.new(file)
nd.handle(:start_element, %w(root level1 level2)) { | e |
	# do something with e
}
nd.handle(:text, %w(root level1 level2 level3)) { | e |
	# reads text inside <level3> tag
}
nd.start() ]]></code>  I'd want it to look similar; basically, the user
				passes a set of tags to the parser which instructs the Stream
				Listener to build sub-trees for.  When a sub-tree is finished
				being built, some event is triggered.</item>
			<item>Allow the user to add entity conversions</item>
			<item>I'd like to hack XMLRPC4R to use REXML, for my own purposes.</item>
			<item status="dropped">I put up an RFC about
				Element.elements.each("xpath") { ...  }, saying that I'd like to
				change it.  So far, the response has
				been mixed, so maybe I'll leave it.  The jury is still out.</item>
			<item status="fixed">Reverse handling of whitespace and
				pretty-printing. (Markus Jais, Tobias Reif)</item>
			<item status="fixed">Optionally not process character entities. This
				is now achieved by :raw.</item>
			<item status="request">Process entity declarations in DocType.</item>
			<item status="fixed">Overload Element constructor to allow passing
				a hash list of attributes. This has been partially achieved.
				Element.add_element can now take a hash, and there is a new
				convenience method add_attributes() which also takes a hash.</item>
		</todo>
	</status>


	<credits>
		<p>I've had help from a number of resources; if I haven't listed you
		here, it means that I just haven't gotten around to adding you, or
		that I'm a dork and have forgotten.  In either case, feel free to
		write me and complain.  I may ignore you, but at least you
		tried. (Actually, I don't conciously ignore anybody except spammers.)</p>
		<list>
			<item><link href="mailto:slumos@mabon.isri.unlv.edu">Steven E Lumos</link>
				for volunteering information about XPath particulars.</item>
			<item><link href="mailto:erik@solidcode.net">Erik Terpstra</link>
				heard my pleas and submitted several logos for REXML.  After sagely
				avoiding choosing one for several weeks, I finally forced my poor
				slave of a wife to pick one (this is what we call "delegation").
				She did, with caveats; Erik quickly made the changes, and the
				result is what you now see at the top of this page.  He also
				supplied a <link href="img/rexml_50p.png">smaller version</link>
				that you can include with your projects that use REXML, if you'd
				like.
			</item>
			<item>Bug fixes provided by: <link
					href="mailto:ukai@debian.or.jp">Fumitoshi UKAI</link> (CData
				metacharacter quoting bug)</item>
			<item><link href="mailto:oliver@debian.org">Oliver M . Bolzer</link>
				is maintaining a Debian package distribution of REXML.  He also has
				provided good feedback and bug reports about namespace support.</item>
			<item><link href="mailto:erne@powernav.com">Ernest Ellingson</link>
				contributed the sourcecode for turning UTF16 and UNILE encodings
				into UTF8, which allowed REXML to get the 100% OASIS valid tests
				rating.</item>
			<item><link href="mailto:maki@inac.co.jp">TAKAHASHI Masayoshi</link>, 
				for information on UTF</item>
			<item><link href="mailto:james@rubyxml.com">James Britt</link> contributed
				code that makes using Document.parse_stream easier to use by allowing 
				it to be passed either a Source, File, or String.
			</item>
			<item><link
			href="http://www.themindelectric.com/products/xml/xml.html">Electric
			XML</link>: This was, after all, the inspiration for REXML.
			Originally, I was just going to do a straight port, and although
			REXML doesn't in any way, shape or form resemble Electric XML,
			still the basic framework and philosophy was inspired by E-XML.
			And I still use E-XML in my Java projects.</item>
			<item><link href="mailto:tobiasreif@pinkjuice.com">Tobias
					Reif</link>: Numerous bug reports, and suggestions for
				improvement.</item>
			<item><link href="http://www.io.com/~jimm/downloads/nqxml/index.html">NQXML</link>:
			While I may complain about the NQXML API, I wrote a few
			applications using it that wouldn't have been written otherwise,
			and it was very useful to me.  It also encouraged me to write
			REXML.  Never complain about free software *slap*.</item>
			<item><link href="mailto:feldt@ce.chalmers.se">Robert
			Feldt</link>: Bug reports and suggestions/recommendations about
			improving REXML.  Testing is one of the most important aspects of
			software development.</item>
		</list>
	</credits>
</documentation>
