1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* test/rexml/: import REXML tests from

http://www.germane-software.com/repos/rexml/trunk/test/.
  Many tests are failed temporary. I'll fix them quickly. Sorry.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29282 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
kou 2010-09-17 13:14:14 +00:00
parent 045491d5be
commit 91ed484f92
89 changed files with 34722 additions and 0 deletions

View file

@ -1,3 +1,9 @@
Fri Sep 17 22:12:23 2010 Kouhei Sutou <kou@cozmixng.org>
* test/rexml/: import REXML tests from
http://www.germane-software.com/repos/rexml/trunk/test/.
Many tests are failed temporary. I'll fix them quickly. Sorry.
Fri Sep 17 16:48:49 2010 URABE Shyouhei <shyouhei@ruby-lang.org>
* test/io/console/test_io_console.rb (TestIO_Console::helper):

Binary file not shown.

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<ProductionSupport version="1.1" >
<Errors>
<CommonErrors>
<CommonError>
<Key><![CDATA[RoyUpdatePolicyBusReq(Object)>>#error:]]></Key>
<Patterns>
<Pattern><![CDATA[The error code is '9997']]></Pattern>
</Patterns>
<Message>
<String>Update Policy request 9997: Please check CICS log</String>
</Message>
<BackendSupport/>
</CommonError>
<CommonError>
<Key>MotorInsuranceContract(Object)>>#error:</Key>
<Patterns>
<Pattern>Have not got a complete</Pattern>
</Patterns>
<Message>
<String>Have not got a complete and consistent set of price matrices for policy period - ask back-end prod supp to sort out</String>
</Message>
<BackendSupport/>
</CommonError>
</CommonErrors>
</Errors>
</ProductionSupport>

25
test/rexml/data/axis.xml Normal file
View file

@ -0,0 +1,25 @@
<?xml version="1.0"?>
<root>
<a>
<a.1/>
<a.2/>
<a.3/>
<a.4/>
<a.5/>
</a>
<b>
<b.1/>
<b.2/>
<b.3/>
<b.4/>
<b.5/>
<b.6/>
<b.7/>
<b.8/>
<b.9/>
</b>
</root>

5
test/rexml/data/bad.xml Normal file
View file

@ -0,0 +1,5 @@
<a>
Here is an XML document.
<b>
It has some elements, but it also has a hidden < error! (or two)
</a>

11
test/rexml/data/basic.xml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<foo>
<bar>
<baz/>
<cheese/>
<baz/>
<cheese/>
<baz/>
</bar>
</foo>

View file

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<xu:modifications xmlns:xu="http://www.xmldb.org/xupdate">
<xu:append select="/foo/bar/cheese[1]">
Goudse kaas
<edam type="jong belegen">Rond</edam>
</xu:append>
<xu:remove select="/foo/bar/baz[2]"/>
<xu:if test="/foo">
<xu:insert-before select="/foo/bar/baz[2]">
<cheese>More cheese!</cheese>
</xu:insert-before>
</xu:if>
<xu:insert-before select="/foo/bar/baz[2]">
<cheese>Even more cheese!</cheese>
</xu:insert-before>
<xu:if test="/bar">
<xu:insert-before select="/foo/bar/baz[2]">
<sausages>No sausages today</sausages>
</xu:insert-before>
</xu:if>
<xu:variable
xmlns:private="http://www.jaxen.org/private"
name="private:twice">
<cracker/>
<!-- champagne -->
<?oisters with a bit of lemon?>
</xu:variable>
<xu:variable name="twice" select="'Twice'"/>
<xu:insert-after
select="/foo/bar"
xmlns:private="http://www.jaxen.org/private"
>
<xu:value-of select="$private:twice"/>
<xu:value-of select="$private:twice"/>
<xu:value-of select="$twice"/>
</xu:insert-after>
</xu:modifications>

View file

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!DOCTYPE rdf:RDF [
<!ENTITY % HTMLlat1 PUBLIC
"-//W3C//ENTITIES Latin 1 for XHTML//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent">
%HTMLlat1;
]>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:on="http://www.oreillynet.com/csrss/"
xmlns="http://purl.org/rss/1.0/"
>
<channel rdf:about="http://www.oreillynet.com/">
<title>O'Reilly Network Articles</title>
<link>http://www.oreillynet.com/</link>
</channel>
</rdf:RDF>

View file

@ -0,0 +1,70 @@
<?xml version="1.0"?>
<?xml-stylesheet href="XSL\JavaXML.html.xsl" type="text/xsl"?>
<?xml-stylesheet href="XSL\JavaXML.wml.xsl" type="text/xsl"
media="wap"?>
<?cocoon-process type="xslt"?>
<!-- Java and XML -->
<JavaXML:Book xmlns:JavaXML="http://www.oreilly.com/catalog/javaxml/"
xmlns:ora="http://www.oreilly.com"
xmlns:unused="http://www.unused.com"
ora:category="Java"
>
<!-- comment one -->
<!-- comment two -->
<JavaXML:Title>Java and XML</JavaXML:Title>
<JavaXML:Contents xmlns:topic="http://www.oreilly.com/topics">
<JavaXML:Chapter topic:focus="XML">
<JavaXML:Heading>Introduction</JavaXML:Heading>
<JavaXML:Topic subSections="7">
What Is It?
</JavaXML:Topic>
<JavaXML:Topic subSections="3">
How Do I Use It?
</JavaXML:Topic>
<JavaXML:Topic subSections="4">
Why Should I Use It?
</JavaXML:Topic>
<JavaXML:Topic subSections="0">
What's Next?
</JavaXML:Topic>
</JavaXML:Chapter>
<JavaXML:Chapter topic:focus="XML">
<JavaXML:Heading>Creating XML</JavaXML:Heading>
<JavaXML:Topic subSections="0">An XML Document</JavaXML:Topic>
<JavaXML:Topic subSections="2">The Header</JavaXML:Topic>
<JavaXML:Topic subSections="6">The Content</JavaXML:Topic>
<JavaXML:Topic subSections="1">What's Next?</JavaXML:Topic>
</JavaXML:Chapter>
<JavaXML:Chapter topic:focus="Java">
<JavaXML:Heading>Parsing XML</JavaXML:Heading>
<JavaXML:Topic subSections="3">Getting Prepared</JavaXML:Topic>
<JavaXML:Topic subSections="3">SAX Readers</JavaXML:Topic>
<JavaXML:Topic subSections="9">Content Handlers</JavaXML:Topic>
<JavaXML:Topic subSections="4">Error Handlers</JavaXML:Topic>
<JavaXML:Topic subSections="0">
A Better Way to Load a Parser
</JavaXML:Topic>
<JavaXML:Topic subSections="4">"Gotcha!"</JavaXML:Topic>
<JavaXML:Topic subSections="0">What's Next?</JavaXML:Topic>
</JavaXML:Chapter>
<JavaXML:SectionBreak/>
<JavaXML:Chapter topic:focus="Java">
<JavaXML:Heading>Web Publishing Frameworks</JavaXML:Heading>
<JavaXML:Topic subSections="4">Selecting a Framework</JavaXML:Topic>
<JavaXML:Topic subSections="4">Installation</JavaXML:Topic>
<JavaXML:Topic subSections="3">
Using a Publishing Framework
</JavaXML:Topic>
<JavaXML:Topic subSections="2">XSP</JavaXML:Topic>
<JavaXML:Topic subSections="3">Cocoon 2.0 and Beyond</JavaXML:Topic>
<JavaXML:Topic subSections="0">What's Next?</JavaXML:Topic>
</JavaXML:Chapter>
</JavaXML:Contents>
</JavaXML:Book>

12
test/rexml/data/dash.xml Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<content-repository>
<content-repository-child-1>
<content-1>content-1-text</content-1>
</content-repository-child-1>
<content-repository-child-2>
<content-2>content-2-text</content-2>
</content-repository-child-2>
<content-repository-child-3>
<content-3>content-3-text</content-3>
</content-repository-child-3>
</content-repository>

View file

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<a xmlns="http://dummyNamespace/">
<b>
<c>Hello</c>
</b>
</a>

View file

@ -0,0 +1,34 @@
<!DOCTYPE internationalization SYSTEM "l10n.dtd" [
<!ENTITY af SYSTEM "af.xml">
<!ENTITY ca SYSTEM "ca.xml">
<!ENTITY cs SYSTEM "cs.xml">
<!ENTITY da SYSTEM "da.xml">
<!ENTITY de SYSTEM "de.xml">
<!ENTITY el SYSTEM "el.xml">
<!ENTITY en SYSTEM "en.xml">
<!ENTITY es SYSTEM "es.xml">
<!ENTITY et SYSTEM "et.xml">
<!ENTITY fi SYSTEM "fi.xml">
<!ENTITY fr SYSTEM "fr.xml">
<!ENTITY hu SYSTEM "hu.xml">
<!ENTITY id SYSTEM "id.xml">
<!ENTITY it SYSTEM "it.xml">
<!ENTITY ja SYSTEM "ja.xml">
<!ENTITY ko SYSTEM "ko.xml">
<!ENTITY nl SYSTEM "nl.xml">
<!ENTITY no SYSTEM "no.xml">
<!ENTITY no_ny SYSTEM "no_ny.xml">
<!ENTITY pl SYSTEM "pl.xml">
<!ENTITY pt SYSTEM "pt.xml">
<!ENTITY pt_br SYSTEM "pt_br.xml">
<!ENTITY ro SYSTEM "ro.xml">
<!ENTITY ru SYSTEM "ru.xml">
<!ENTITY sk SYSTEM "sk.xml">
<!ENTITY sl SYSTEM "sl.xml">
<!ENTITY sr SYSTEM "sr.xml">
<!ENTITY sv SYSTEM "sv.xml">
<!ENTITY tr SYSTEM "tr.xml">
<!ENTITY zh_cn SYSTEM "zh_cn.xml">
<!ENTITY zh_tw SYSTEM "zh_tw.xml">
]>
<x/>

View file

@ -0,0 +1,542 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="http://www.germane-software.com/repositories/public/documentation/documentation.css"?>
<?xml-stylesheet alternative="yes" type="text/css" href="file:/home/ser/Work/documentation/documentation.css"?>
<?xml-stylesheet alternative="yes" type="text/xsl" href="http://www.germane-software.com/repositories/public/documentation/paged.xsl"?>
<!DOCTYPE documentation SYSTEM "http://www.germane-software.com/repositories/public/documentation/documentation.dtd">
<documentation>
<head>
<title>REXML</title>
<banner href="img/rexml.png" />
<version>@ANT_VERSION@</version>
<date>@ANT_DATE@</date>
<home>http://www.germane-software.com/software/rexml</home>
<base>rexml</base>
<language>ruby</language>
<author email="ser@germane-software.com"
href="http://www.ser1.net/" jabber="seanerussell@gmail.com">Sean
Russell</author>
</head>
<overview>
<purpose lang="en">
<p>REXML is a conformant XML processor for the Ruby programming
language. REXML 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. REXML is
included in the standard library of Ruby</p>
<p>This software is distribute under the <link href="LICENSE.txt">Ruby
license</link>.</p>
</purpose>
<general>
<p>REXML arose out of a desire for a straightforward XML API, and is an
attempt at an API that doesn't require constant referencing of
documentation to do common tasks. "Keep the common case simple, and the
uncommon, possible."</p>
<p>REXML avoids The DOM API, which violates the maxim of simplicity. It
does provide <em>a</em> DOM model, but one that is Ruby-ized. It is an
XML API oriented for Ruby programmers, not for XML programmers coming
from Java.</p>
<p>Some of the common differences are that the Ruby API relies on block
enumerations, rather than iterators. For example, the Java code:</p>
<example>for (Enumeration e=parent.getChildren(); e.hasMoreElements(); ) {
Element child = (Element)e.nextElement(); // Do something with child
}</example>
<p>in Ruby becomes:</p>
<example>parent.each_child{ |child| # Do something with child }</example>
<p>Can't you feel the peace and contentment in this block of code? Ruby
is the language Buddha would have programmed in.</p>
<p>One last thing. If you use and like this software, and you're in a
position of power in a company in Western Europe and are looking for a
software architect or developer, drop me a line. I took a lot of French
classes in college (all of which I've forgotten), and I lived in Munich
long enough that I was pretty fluent by the time I left, and I'd love to
get back over there.</p>
</general>
<features lang="en">
<item>Four intuitive parsing APIs.</item>
<item>Intuitive, powerful, and reasonably fast tree parsing API (a-la
DOM</item>
<item>Fast stream parsing API (a-la SAX)<footnote>This is not a SAX
API.</footnote></item>
<item>SAX2-based API<footnote>In addition to the native REXML streaming
API. This is slower than the native REXML API, but does a lot more work
for you.</footnote></item>
<item>Pull parsing API.</item>
<item>Small</item>
<item>Reasonably fast (for interpreted code)</item>
<item>Native Ruby</item>
<item>Full XPath support<footnote>Currently only available for the tree
API</footnote></item>
<item>XML 1.0 conformant<footnote>REXML passes all of the non-validating
OASIS tests. There are probably places where REXML isn't conformant, but
I try to fix them as they're reported.</footnote></item>
<item>ISO-8859-1, UNILE, UTF-16 and UTF-8 input and output; also,
support for any encoding the iconv supports.</item>
<item>Documentation</item>
</features>
</overview>
<operation lang="en">
<subsection title="Installation">
<p>You don't <em>have</em> to install anything; if you're running a
version of Ruby greater than 1.8, REXML is included. However, if you
choose to upgrade from the REXML distribution, run the command:
<code>ruby bin/install.rb</code>. 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 bin/install.rb -u</code>.</p>
</subsection>
<subsection title="Unit tests">
<p>If you have Test::Unit installed, you can run the unit test cases.
Run the command: <code>ruby bin/suite.rb</code>; it runs against the
distribution, not against the installed version.</p>
</subsection>
<subsection title="Benchmarks">
<p>There is a benchmark suite in <code>benchmarks/</code>. To run the
benchmarks, change into that directory and run <code>ruby
comparison.rb</code>. If you have nothing else installed, only the
benchmarks for REXML will be run. However, if you have any of the
following installed, benchmarks for those tools will also be run:</p>
<list>
<item>NQXML</item>
<item>XMLParser</item>
<item>Electric XML (you must copy <code>EXML.jar</code> into the
<code>benchmarks</code> directory and compile
<code>flatbench.java</code> before running the test)</item>
</list>
<p>The results will be written to <code>index.html</code>.</p>
</subsection>
<subsection title="General Usage">
<p>Please see <link href="docs/tutorial.html">the Tutorial</link>.</p>
<p>The API documentation is available <link
href="http://www.germane-software.com/software/XML/rexml/doc">on-line</link>,
or it can be downloaded as an archive <link
href="http://www.germane-software.com/software/archives/rexml_api_@ANT_VERSION@.tgz">in
tgz format (~70Kb)</link> or (if you're a masochist) <link
href="http://www.germane-software.com/software/archives/rexml_api_@ANT_VERSION@.zip">in
zip format (~280Kb)</link>. The best solution is to download and install
Dave Thomas' most excellent <link
href="http://rdoc.sourceforge.net">rdoc</link> and generate the API docs
yourself; then you'll be sure to have the latest API docs and won't have
to keep downloading the doc archive.</p>
<p>The unit tests in <code>test/</code> and the benchmarking code in
<code>benchmark/</code> provide additional examples of using REXML. The
Tutorial provides examples with commentary. The documentation unpacks
into <link href="doc/index.html"><code>rexml/doc</code></link>.</p>
<p>Kouhei Sutou maintains a <link
href="http://www.germane-software.com/software/rexml_doc_ja/current/index.html">Japanese
version</link> of the REXML API docs. <link
href="http://www.germane-software.com/software/rexml_doc_ja/current/japanese_documentation.html">Kou's
documentation page</link> contains links to binary archives for various
versions of the documentation.</p>
</subsection>
</operation>
<status>
<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 four things: speed, size, completeness, 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. 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>REXML is a conformant XML 1.0 parser. It supports multiple language
encodings, and internal processing uses the required UTF-8 and UTF-16
encodings. It passes 100% of the Oasis non-validating tests.
Furthermore, it provides a full implementation of XPath, a SAX2 and a
PullParser API.</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>
</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="RSS">
<p>An <link
href="http://www.germane-software.com/projects/rexml/timeline?ticket=on&amp;max=50&amp;daysback=90&amp;format=rss">RSS
file</link> for REXML is now being generated from the change log. This
allows you to be alerted of bug fixes and feature additions via "pull".
<link href="http://www.germane-software.com/software/rexml/rss.xml">Another
RSS</link> is available which contains a single item: the release notice
for the most recent release. This is an abuse of the RSS
mechanism, which was intended to be a distribution system for headlines
linked back to full articles, but it works. The headline for REXML is
the version number, and the description is the change log. The links all
link back to the REXML home page. The URL for the RSS itself is
http://www.germane-software.com/software/rexml/rss.xml.</p>
<p>The <link href="release.html">changelog itself is here</link>.</p>
<p>For those who are interested, there's a <link
href="docs/sloccount.txt">SLOCCount</link> (by David A. Wheeler) file
with stats on the REXML sourcecode. Note that the SLOCCount output
includes the files in the test/, benchmarks/, and bin/ directories, as
well as the main sourcecode for REXML itself.</p>
</subsection>
<subsection title="Applications that use REXML">
<list>
<item><link
href="http://www.pablotron.org/software/raggle/">Raggle</link> is a
console-based RSS aggregator.</item>
<item><link
href="http://www.zweknu.org/technical/index.rhtml?s=p|10/">getrss</link>
is an RSS aggregator</item>
<item>Ned Konz's <link
href="http://www.bikenomad.microship.com/ruby/">ruby-htmltools</link>
uses REXML</item>
<item>Hiroshi NAKAMURA's <link
href="http://www.ruby-lang.org/en/raa-list.rhtml?name=SOAP4R">SOAP4R</link>
package can use REXML as the XML processor.</item>
<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>
site is generated with scripts that use REXML. RubyXML is a great
place to find information about th intersection between Ruby and
XML.</item>
</list>
</subsection>
<bugs lang="en">
<p>You can submit bug reports and feature requests, and view the list of
known bugs, at the <link
href="http://www.germane-software.com/projects/rexml">REXML bug report
page.</link> Please do submit bug reports. If you really want your bug
fixed fast, include an runit or Test::Unit method (or methods) that
illustrates the problem. At the very least, send me some XML that REXML
doesn't process properly.</p>
<p>You don't have to send an entire test suite -- just the unit test
methods. If you don't send me a unit test, I'll have to write one
myself, which will mean that your bug will take 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. Include your email if you want a response about the bug.</p>
<item>Attributes are not handled internally as nodes, so you can't
perform node functions on them. This will have to change. It'll also
probably mean that, rather than returning attribute values, XPath will
return the Attribute nodes.</item>
<item>Some of the XPath <em>functions</em> are untested<footnote>Mike
Stok has been testing, debugging, and implementing some of these
Functions (and he's been doing a good job) so there's steady improvement
in this area.</footnote>. Any XPath functions that don't work are also
bugs... please report them. If you send a unit test 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>Accessing prefixes for which there is no defined namespace in an
XPath should throw an exception. It currently doesn't -- it just fails
to match.</item>
</bugs>
<todo lang="en">
<item>Reparsing a tree with a pull/SAX parser</item>
<item>Better namespace support in SAX</item>
<item>Lazy tree parsing</item>
<item>Segregate parsers, for optimized minimal distributions</item>
<item>XML &lt;-&gt; Ruby</item>
<item>Validation support</item>
<item>True XML character support</item>
<item>Add XPath support for streaming APIs</item>
<item status="request">XQuery support</item>
<item status="request">XUpdate support</item>
<item>Make sure namespaces are supported in pull parser</item>
<item status="request">Add document start and entity replacement events
in pull parser</item>
<item>Better stream parsing exception handling</item>
<item>I'd like to hack XMLRPC4R to use REXML, for my own
purposes.</item>
</todo>
</status>
<faq>
<q>REXML is hanging while parsing one of my XML files.</q>
<a>Your XML is probably malformed. Some malformed XML, especially XML that
contains literal '&lt;' embedded in the document, causes REXML to hang.
REXML should be throwing an exception, but it doesn't; this is a bug. I'm
aware that it is an extremely annoying bug, and it is one I'm trying to
solve in a way that doesn't significantly reduce REXML's parsing
speed.</a>
<q>I'm using the XPath '//foo' on an XML branch node X, and keep getting
all of the 'foo' elements in the entire document. Why? Shouldn't it return
only the 'foo' element descendants of X?</q>
<a>No. XPath specifies that '/' returns the document root, regardless of
the context node. '//' also starts at the document root. If you want to
limit your search to a branch, you need to use the self:: axe. EG,
'self::node()//foo', or the shorthand './/foo'.</a>
<q>I want to parse a document both as a tree, and as a stream. Can I do
this?</q>
<a>Yes, and no. There is no mechanism that directly supports this in
REXML. However, aside from writing your own traversal layer, there is a
way of doing this. To turn a tree into a stream, just turn the branch you
want to process as a stream back into a string, and re-parse it with your
preferred API. EG: pp = PullParser.new( some_element.to_s ). The other
direction is more difficult; you basically have to build a tree from the
events. REXML will have one of these builders, eventually, but it doesn't
currently exist.</a>
<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>
<q>I'm trying to create an ISO-8859-1 document, but when I add text to the
document it isn't being properly encoded.</q>
<a>Regardless of what the encoding of your document is, when you add text
programmatically to a REXML document you <em>must</em> ensure that you are
only adding UTF-8 to the tree. In particular, you can't add ISO-8859-1
encoded text that contains characters above 0x80 to REXML trees -- you
must convert it to UTF-8 before doing so. Luckily, this is easy:
<code>text.unpack('C*').pack('U*')</code> will do the trick. 7-bit ASCII
is identical to UTF-8, so you probably won't need to worry about this.</a>
<q>How do I get the tag name of an Element?</q>
<a>You take a look at the APIs, and notice that <code>Element</code>
includes <code>Namespace</code>. Then you click on the
<code>Namespace</code> link and look at the methods that
<code>Element</code> includes from <code>Namespace</code>. One of these is
<code>name()</code>. Another is <code>expanded_name()</code>. Yet another
is <code>prefix()</code>. Then, you email the author of rdoc and ask him
to extend rdoc so that it lists methods in the API that are included from
other files, so that you don't have to do all of that looking around for
your method.</a>
</faq>
<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.</p>
<list>
<item>Mike Stok has been very active, sending not only fixes for bugs
(especially in Functions), but also by providing unit tests and making
sure REXML runs under Ruby 1.7. He also sent the most awesome hand
knitted tea cozy, with "REXML" and the Ruby knitted into it.</item>
<item>Kouhei Sutou translated the REXML API documentation to Japanese!
Links are in the API docs section of the main documentation. He has also
contributed a large number of bug reports and patches to fix bugs in
REXML.</item>
<item>Erik Terpstra heard my pleas and submitted several logos for
REXML. After sagely procrastinating 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>Ernest Ellingson contributed the sourcecode for turning UTF16 and
UNILE encodings into UTF8, which allowed REXML to get the 100% OASIS
valid tests rating.</item>
<item>Ian Macdonald provided me with a comprehensive, well written RPM
spec file.</item>
<item>Oliver M . Bolzer is maintaining a Debian package distribution of
REXML. He also has provided good feedback and bug reports about
namespace support.</item>
<item>Michael Granger supplied a patch for REXML that make the unit
tests pass under Ruby 1.7.</item>
<item>James Britt 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>Tobias Reif: Numerous bug reports, and suggestions for
improvement.</item>
<item>Stefan Scholl, who provided a lot of feedback and bug reports
while I was trying to get ISO-8859-1 support working.</item>
<item>Steven E Lumos for volunteering information about XPath
particulars.</item>
<item>Fumitoshi UKAI provided some bug fixes for CData metacharacter
quoting.</item>
<item>TAKAHASHI Masayoshi, for information on UTF</item>
<item>Robert Feldt: Bug reports and suggestions/recommendations about
improving REXML. Testing is one of the most important aspects of
software development.</item>
<item><link
href="http://www.themindelectric.com/exml/index.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="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>See my <link
href="http://www.germane-software.com/~ser/technology.html">technologies
page</link> for a more comprehensive list of computer technologies that
I depend on for my day-to-day work.</item>
<item>rdoc, an excellent JavaDoc analog<footnote>When I was first
working on REXML, rdoc wasn't, IMO, very good, so I wrote API2XML.
API2XML was good enough for a while, and then there was a flurry of work
on rdoc, and it quickly surpassed API2XML in features. Since I was never
really interested in maintaining a JavaDoc analog, I stopped support of
API2XML, and am now recommending that people use
rdoc.</footnote>.</item>
<item>Many, many other people who've submitted bug reports, suggestions,
and positive feedback. You're all co-developers!</item>
</list>
</credits>
</documentation>

296
test/rexml/data/euc.xml Normal file
View file

@ -0,0 +1,296 @@
<?xml version="1.0" encoding="euc-jp"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN">
<html xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=euc-jp" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta name="author" content="U.Nakamura" />
<link rev="made" href="mailto:usa@ruby-lang.org" />
<link rel="StyleSheet" href="./ruby.css" type="text/css" />
<title>Ruby-mswin32</title>
</head>
<body>
<h1><a id="top">Ruby-mswin32</a></h1>
<p>あるいは、Windowsとの終わりなき戦い ;-(</p>
<p>[日本語 / <a href="./index_en.html">English</a>]</p>
<h2><a id="menu">▼ 目次</a></h2>
<ul>
<li><a href="#remark">注意事項</a></li>
<li><a href="#ruby">Rubyとは?</a></li>
<li><a href="#mswin32">mswin32版rubyとは?</a></li>
<li><a href="#download">バイナリ ダウンロード</a></li>
<li><a href="#install">インストール</a></li>
<li><a href="#recent">最近の出来事</a></li>
<li><a href="#link">リンク</a></li>
</ul>
<h2><a id="remark">▼ 注意事項</a></h2>
<p>このページでは、mswin32版rubyの配布と変更状況のお知らせを行っています。</p>
<p>ここは別に公式ページでもなんでもなくて、私が勝手に書いてるページです。ここで入手できるプログラム・情報(無いに等しいけど)については、各自の判断でご利用ください。<br />
問い合わせは<a href="mailto:usa@ruby-lang.org"></a>へ。間違っても他の人に迷惑をかけるようなことはしないでね。</p>
<h2><a id="ruby">▼ Rubyとは?</a></h2>
<p><a href="http://www.ruby-lang.org/ja/">Rubyのサイト</a>をご覧下さい。</p>
<h2><a id="mswin32">▼ mswin32版rubyとは?</a></h2>
<p>mswin32版rubyとは、32bit版Windows(Windows95・Windows98・WindowsMe・Windows NT・Windows 2000・WindowsXP・Windows 2003 Server、以下Windowsと表記)上で動作するRubyのバイナリの一つです。<br />
Windows上で動作するRubyとしては、現在、5種類のバイナリが存在します。これらはそれぞれmswin32版・cygwin版・mingw32版・bccwin32版・djgpp版と呼ばれています。<br />
それぞれの違いをまとめると以下のようになります(事実誤認があればお知らせください)。</p>
<dl>
<dt><a id="label:1">mswin32版</a></dt><dd>
<p>VC++でコンパイルされる。Windowsから見ればもっとも「普通」のバイナリと言えるが、反面、Rubyが持つUNIXで特徴的な機能の一部が使用できない。1.7.3以降はmingw32版と拡張ライブラリについてはバイナリ互換性がある。<br />
RUBY_PLATFORMは*-mswin32。</p>
</dd>
<dt><a id="label:2">cygwin版</a></dt><dd>
<p>gccでコンパイルされ、<a href="http://sources.redhat.com/cygwin/">cygwin</a>環境で動作する。cygwin環境がUNIXライクな環境をWindows上で構築するものであるので、当然、cygwin版rubyは一般のUNIX用のものとだいたい同じように動作する(ことが期待できる)。<br />
RUBY_PLATFORMは*-cygwin。</p>
</dd>
<dt><a id="label:3">mingw32版</a></dt><dd>
<p>gccでコンパイルされる。ソースはほとんどmswin32版と共通であり、ランタイムライブラリも共通(MSVCRT.dll)なので、動作も(おそらく)mswin32版とほぼ同じ。1.7.3以降はmswin32版と拡張ライブラリについてはバイナリ互換性がある。<br />
RUBY_PLATFORMは*-mingw32。</p>
</dd>
<dt><a id="label:4">bccwin32版</a></dt><dd>
<p>BC++でコンパイルされる。ソースはかなりの部分がmswin32版と共通ではあるが、ランタイムライブラリが異なるので、細かいところで挙動がmswin32版とは異なる(はず)。1.7以降でサポートされる。<br />
RUBY_PLATFORMは*-bccwin32。</p>
</dd>
<dt><a id="label:5">djgpp版</a></dt><dd>
<p>DJGPPでコンパイルされる。DOS用のバイナリなので、もちろんDOSでも動作する。反面、WindowsにあってDOSにない機能の多くが使えない(ネットワーク関連など)。<br />
RUBY_PLATFORMは*-msdosdjgpp。</p>
</dd>
</dl>
<p>このページでは、上記のうちmswin32版のみを扱っています。<br />
なお、cygwin版・mingw32版・djgpp版についてはわたなべさんの<a href="http://www.os.rim.or.jp/~eban/">Ruby binaries</a>から入手可能です。また、bccwin32版については小西さんの<a href="http://www001.upp.so-net.ne.jp/konishi/ruby/index.htm">Ruby</a>から入手可能です。</p>
<h2><a id="download">▼ バイナリ ダウンロード</a></h2>
<p>現在配布中の全てのバイナリはVC++ 5.0(Version 11.00.7022 for 80x86)でmakeしたものです。ruby自体に関しては、<a href="http://www.ruby-lang.org/ja/download.html">標準配布のソース</a>(または<a href="http://www.ruby-lang.org/~knu/cvsrepo-guide.html">CVS</a>のソース)からそのまま作成しています。拡張ライブラリについては各々のリンク先を参照してください。<br />
いずれのバイナリもzip形式でアーカイブされています。</p>
<p>md5sumのチェック方法ですが、例えばrubyがインストールされているなら下記のような方法があります。<br />
<code>ruby -r md5 -e "puts MD5.new(File.open('filename', 'rb').read).hexdigest"</code></p>
<h3><a id="release">Release</a></h3>
<ul>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.8.1-i386-mswin32.zip">ruby-1.8.1-i386-mswin32.zip</a> (3,764KB) <em>最新Release版</em><br />
ruby 1.8.1 (2003-12-25) [i386-mswin32]<br />
md5sum : 6bbdabeb29f1a15fa69901e87d1108ac</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.8.0-i386-mswin32.zip">ruby-1.8.0-i386-mswin32.zip</a> (2,507KB)<br />
ruby 1.8.0 (2003-08-04) [i386-mswin32]<br />
md5sum : eaf9263062429fd4f722d9a70a38a9dc</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.6.8-i586-mswin32.zip">ruby-1.6.8-i586-mswin32.zip</a> (1,964KB)<br />
ruby 1.6.8 (2002-12-24) [i586-mswin32]<br />
md5sum : f704f1248ec25b96e3e1f3070afa915e</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.6.7-i586-mswin32.zip">ruby-1.6.7-i586-mswin32.zip</a> (1,972KB)<br />
ruby 1.6.7 (2002-03-01) [i586-mswin32]<br />
md5sum : ddedc40d0fc3b0ea1d6ac74f4976bfc6</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.6.6-i586-mswin32.zip">ruby-1.6.6-i586-mswin32.zip</a> (1,944KB)<br />
ruby 1.6.6 (2001-12-26) [i586-mswin32]<br />
md5sum : 96e0d1d19a37e5e7e50ae7ce99e34636</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.6.5-i586-mswin32.zip">ruby-1.6.5-i586-mswin32.zip</a> (1,896KB)<br />
ruby 1.6.5 (2001-09-19) [i586-mswin32]<br />
md5sum : c708ae98a05df2ff8dea5a70e3791bfa</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.6.4-i586-mswin32.zip">ruby-1.6.4-i586-mswin32.zip</a> (1,821KB)<br />
ruby 1.6.4 (2001-06-04) [i586-mswin32]<br />
md5sum : cf813ca19e40be164057b3562575e4da</li>
</ul>
<h3><a id="develop">Developing versions snapshots</a></h3>
<ul>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.9.0-20040126-i386-mswin32.zip">ruby-1.9.0-20040126-i386-mswin32.zip</a> (3,849KB)<br />
ruby 1.9.0 (2004-01-26) [i386-mswin32]<br />
md5sum : fffafbf881cb6a85982220eae5a5b4f5</li>
</ul>
<h3><a id="stable">Stable versions snapshots</a></h3>
<h4><a id="stable">1.8.0</a></h4>
<ul>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.8.1-20040127-i386-mswin32.zip">ruby-1.8.1-20040127-i386-mswin32.zip</a> (3,822KB)<br />
ruby 1.8.1 (2004-01-27) [i386-mswin32]<br />
md5sum : 1fc0d5f53f0a75d0c6d1ca5d21082089</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.8.1-20031027-i386-mswin32.zip">ruby-1.8.1-20031027-i386-mswin32.zip</a> (3,075KB)<br />
ruby 1.8.1 (2003-10-27) [i386-mswin32]<br />
md5sum : 9dbdc644c529d207d0bda5d64478a5c4</li>
</ul>
<h4><a id="stable">1.6.8</a></h4>
<ul>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.6.8-20030727-i586-mswin32.zip">ruby-1.6.8-20030727-i586-mswin32.zip</a> (2,093KB)<br />
ruby 1.6.8 (2003-07-27) [i586-mswin32]<br />
md5sum : 28c3b92b162319b3d6bc99c9996cad15</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.6.8-20030515-i586-mswin32.zip">ruby-1.6.8-20030515-i586-mswin32.zip</a> (2,091KB)<br />
ruby 1.6.8 (2003-05-15) [i586-mswin32]<br />
md5sum : e5f6558de261d111add4f657ad5e345f</li>
</ul>
<h3><a id="ext">Extension libraries</a></h3>
<h4><a id="ext">1.8.0</a></h4>
<ul>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/racc-1.4.4-all-i386-mswin32-1.8.zip">racc-1.4.4-all-i386-mswin32-1.8.zip</a> (70KB)<br />
<a href="http://www.loveruby.net/en/racc.html">racc</a> 1.4.4-all (for ruby 1.8.1)<br />
md5sum : 46c4d48b714fb1ded880e7e7af456b28</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/vrswin-030906-i386-mswin32-1.8.zip">vrswin-030906-i386-mswin32-1.8.zip</a> (54KB)<br />
<a href="http://www.osk.3web.ne.jp/~nyasu/vruby/vrproject-e.html">VisualuRuby (swin)</a> 030906 (for ruby 1.8.0)<br />
md5sum : 11c2d30e2a05e9ea7e097ec7b066cedf</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/vruby-030906-i386-mswin32-1.8.zip">vruby-030906-i386-mswin32-1.8.zip</a> (96KB)<br />
<a href="http://www.osk.3web.ne.jp/~nyasu/vruby/vrproject-e.html">VisualuRuby (vruby)</a> 030906 (for ruby 1.8.0)<br />
md5sum : 77a42995e42e869932f5fb282cc297ea</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/eruby-1.0.4-i386-mswin32-1.8.zip">eruby-1.0.4-i386-mswin32-1.8.zip</a> (75KB)<br />
<a href="http://www.modruby.net/">eruby</a> 1.0.4 (for ruby 1.8.0)<br />
md5sum : de7282647f015b1d20a28dcf7c2b8715</li>
</ul>
<h4><a id="ext">1.6.8</a></h4>
<ul>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/vrswin-030521-i586-mswin32-1.6.zip">vrswin-030521-i586-mswin32-1.6.zip</a> (55KB)<br />
<a href="http://www.osk.3web.ne.jp/~nyasu/vruby/vrproject-e.html">VisualuRuby (swin)</a> 030521 (for ruby 1.6.8)<br />
md5sum : eae3284c6f79be7a119858ff9e940985</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/vruby-030517-i586-mswin32-1.6.zip">vruby-030517-i586-mswin32-1.6.zip</a> (95KB)<br />
<a href="http://www.osk.3web.ne.jp/~nyasu/vruby/vrproject-e.html">VisualuRuby (vruby)</a> 030517 (for ruby 1.6.8)<br />
md5sum : a32af752428cf3aa03000d66d8deca33</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/tmail-0.10.7-i586-mswin32-1.6.zip">tmail-0.10.7-i586-mswin32-1.6.zip</a> (160KB)<br />
<a href="http://www.loveruby.net/en/tmail.html">TMail</a> 0.10.7 (for ruby 1.6.8)<br />
md5sum : 74351ed81550dfbf3bfaf8252c316326</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/eruby-1.0.3-i586-mswin32-1.6.zip">eruby-1.0.3-i586-mswin32-1.6.zip</a> (74KB)<br />
<a href="http://www.modruby.net/">eruby</a> 1.0.3 (for ruby 1.6.8)<br />
md5sum : e05d654128422846f86ca84f55bf7bcb</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/rubywin-0.0.4.3-i586-mswin32-1.6.zip">rubywin-0.0.4.3-i586-mswin32-1.6.zip</a> (286KB)<br />
<a href="http://homepage1.nifty.com/markey/ruby/rubywin/index_e.html">RubyWin</a> 0.0.4.3 (for ruby 1.6.8)<br />
md5sum : 3f2226ef0c6e41b31c2f337f778e3e18</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/shim-20021224-i586-mswin32-1.6.zip">shim-20021224-i586-mswin32-1.6.zip</a> (138KB)<br />
<a href="http://www.ruby-lang.org/~knu/cgi-bin/cvsweb.cgi/shim/">Ruby Shim</a> 20021224 (for ruby 1.6.8)<br />
md5sum : 7ee4363195973a1df0584cb467e5ce82</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/racc-1.4.3-all-i586-mswin32-1.6.zip">racc-1.4.3-all-i586-mswin32-1.6.zip</a> (124KB)<br />
<a href="http://www.loveruby.net/en/racc.html">racc</a> 1.4.3-all (for ruby 1.6.8)<br />
md5sum : 1f093aabb464bef3074112949228a8c6</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/win32ole-0.5.2-i586-mswin32-1.6.zip">win32ole-0.5.2-i586-mswin32-1.6.zip</a> (59KB)<br />
<a href="http://homepage1.nifty.com/markey/ruby/win32ole/index_e.html">Win32OLE</a> 0.5.2 (for ruby 1.6.8)&lt;<br />
md5sum : 960f7205923a9243cff567d291b254ad</li>
<li><a href="ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ext/uconv-0.4.11-i586-mswin32-1.6.zip">uconv-0.4.11-i586-mswin32-1.6.zip</a> (110KB)<br />
<a href="http://www.yoshidam.net/Ruby.html#uconv">uconv</a> 0.4.11 (for ruby 1.6.8)<br />
md5sum : c08f3662abee8e7186283741f89b88d7</li>
</ul>
<h2><a id="install">▼ インストール</a></h2>
<p>上記のバイナリをインストールする場合は、お好みのディレクトリ(以下<code>$TOPDIR</code>と記述)に展開してください。ディレクトリ付きで圧縮されてますので、展開時にはディレクトリ付きで展開するのを忘れずに(意味がわからない人は気にしなくていいです)。<br />
展開後は、<code>$TOPDIR\bin</code><code>PATH</code>を通しておいてください。</p>
<p>なお、以下の拡張ライブラリは、この配布物に含まれない外部のライブラリに依存しています。</p>
<ul>
<li>curses.so : PDCursesに依存しています。</li>
<li>dbm.so : GDBMに依存しています。</li>
<li>gdbm.so : GDBMに依存しています。</li>
<li>iconv.so : Iconvに依存しています。</li>
<li>openssl.so : OpenSSLに依存しています。</li>
<li>readline.so : readlineに依存しています。</li>
<li>tcltklib.so : Tcl/Tkに依存しています。</li>
<li>zlib.so : Zlibに依存しています。</li>
</ul>
<p>上記のうち、PDCurses・GDBM・OpenSSL・readline・Zlibについては、<a href="http://jarp.jin.gr.jp/win32/">Porting Libraries to Win32</a>にバイナリが存在します。<br />
Iconvについては、Meadowy.orgで配布されている<a href="http://www.meadowy.org/meadow/dists/snapshot/iconv-1.8.win32.zip">iconv-1.8.win32.zip</a>を利用しています。<br />
Tcl/Tkについては、<a href="http://www.activestate.com/">ActiveState</a>で配布されている<a href="http://www.activestate.com/Products/ActiveTcl/">ActiveTcl</a>を利用しています。</p>
<h2><a id="recent">▼ 最近の出来事</a></h2>
<h3><a id="d20040127">2004-01-27</a></h3>
<p>あけましておめでとうございます。って遅いよ!</p>
<p>ruby-1.8.1-20040127とruby-1.9.0-20040126を置きました。<br />
前者は主に1.8.1リリース版で発見された不具合の修正です。後者は開発版。</p>
<h3><a id="d20031225">2003-12-25</a></h3>
<p>メリークリスマス! ruby-1.8.1がリリースされました!<br />
(previewを一つ飛ばしちゃいました、ごめんなさい...)</p>
<h3><a id="d20031206">2003-12-06</a></h3>
<p>ruby-1.8.1-preview3を置きました。思いのほか間が空いちゃいましたね。</p>
<h3><a id="d20031101">2003-11-01</a></h3>
<p>ruby-1.8.1-preview2を置きました。</p>
<h3><a id="d20031028">2003-10-28</a></h3>
<p>ruby-1.8.1-20031027を置きました。<br />
racc-1.4.4-allを置きました。</p>
<h3><a id="d20030907">2003-09-07</a></h3>
<p>eruby-1.0.4・vrswin-030906・vruby-030906を置きました。</p>
<h3><a id="d20030812">2003-08-12</a></h3>
<p>ruby-1.8.0-20030812を置きました。</p>
<p>vrswin-030811・vruby-030811を置きました。今回から置く拡張ライブラリは全て1.8用になります。</p>
<h3><a id="d20030804">2003-08-04</a></h3>
<p>ruby-1.8.0を置きました。Ruby 1.8系最初のリリースとなります。<br />
1.6系からの変更点については、<a href="ftp://ftp.ruby-lang.org/pub/ruby/1.8/changes.1.8.0">changes.1.8.0</a>などをご覧ください。</p>
<h3><a id="d20030731">2003-07-31</a></h3>
<p>ruby-1.8.0-preview6を置きました。えーと、これを含めてあと2回previewが出る模様です :)</p>
<h3><a id="d20030728">2003-07-28</a></h3>
<p>ruby-1.8.0-preview5を置きました。おそらくこれが1.8.0の最後のpreviewになるでしょう。<br />
ruby-1.6.8-20030727を置きました。</p>
<h3><a id="old">かつての出来事</a></h3>
<p><a href="./old.html">こちら</a>をどうぞ。</p>
<h2><a id="link">▼ リンク</a></h2>
<p>mswin32版に関する(と思われる)リンクです。勝手に張ってますので、不都合があれば<a href="mailto:usa@osb.att.ne.jp"></a>までご連絡ください。</p>
<ul>
<li><a href="http://www.ruby-lang.org/">Ruby Home Page</a> (<a href="http://www.ruby-lang.org/ja/">日本語</a> / <a href="http://www.ruby-lang.org/en/">English</a>)<br />
言わずとしれた、本家サイト。</li>
<li>雑記帳 (<a href="http://homepage1.nifty.com/markey/">日本語</a> / <a href="http://homepage1.nifty.com/markey/index_e.html">English</a>)<br />
助田さんのページ。<a href="http://homepage1.nifty.com/markey/ruby/rubywin/index.html">RubWin</a><a href="http://homepage1.nifty.com/markey/ruby/win32ole/index.html">Win32OLE</a>などがあります。</li>
<li><a href="http://www.moonwolf.com/ruby/">Script/Ruby</a> (日本語)<br />
MoonWolfさんのページ。Win32Moduleなどがあります。</li>
<li>ActiveScriptRuby (<a href="http://www.geocities.co.jp/SiliconValley-PaloAlto/9251/ruby/index.html">日本語</a> / <a href="http://www.geocities.co.jp/SiliconValley-PaloAlto/9251/ruby/main.html">English</a>)<br />
artonさんのページ。Windows版Rubyの未来はここにあるのかも。</li>
<li>VisualuRuby計画(仮称) (<a href="http://www.osk.3web.ne.jp/~nyasu/software/vrproject.html">日本語</a> / <a href="http://www.osk.3web.ne.jp/~nyasu/vruby/vrproject-e.html">English</a>)<br />
nyasuさんのページ。VisualuRubyなどがあります(ってこれもそのまんま)。WindowsでRubyを使うための<a href="http://www.osk.3web.ne.jp/~nyasu/software/rubyonwin.html">リンク集</a>が充実してます。ちなみに、当サイトのデザインはこちらのパクリです。多謝!</li>
<li>Ruby (<a href="http://www.yoshidam.net/Ruby_ja.html">日本語</a> / <a href="http://www.yoshidam.net/Ruby.html">English</a>)<br />
よしだむさんのページ。<a href="http://www.yoshidam.net/Ruby_ja.html#susie">Susieプラグインライブラリ</a><a href="http://www.yoshidam.net/Ruby_ja.html#rddraw">DirectDraw for Ruby</a>などがあります。</li>
<li><a href="http://homepage2.nifty.com/sakazuki/rde.html">RDE(Ruby Development Environment)</a> (日本語)<br />
sakazukiさんのページ。mswin32版ユーザなら必見です。推奨環境はartonさんとこのActiveScriptRubyですが (^^; ここの配布物を使っても問題なく動作します。</li>
</ul>
<p class="footer">
[<a href="../">戻る</a>]
</p>
<address>written by <a href="mailto:usa@ruby-lang.org">U.Nakamura</a></address>
<p class="versions">
ruby 1.9.0 (2004-01-13)<br />
ERb 2.0.4<br />
RDtool 0.6.11<br />
rublog 0.0.2
</p>
</body>
</html>

View file

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<evaluate>
<data>
<jumps>
<subject>
<the/>
<fox color="brown"/>
<speed category="quick"/>
</subject>
<over/>
<object>
<the/>
<dog color="unspecified"/>
<speed category="lazy"/>
</object>
</jumps>
</data>
<!-- there is one element with attribute color="brown" should this
meta-test should succeed -->
<metatest select="//@color">brown</metatest>
<!-- there is no element with attribute category="moderate" -->
<metatest select="//speed/@category">moderate</metatest>
</evaluate>

29
test/rexml/data/fibo.xml Normal file
View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<Fibonacci_Numbers>
<fibonacci index="0">0</fibonacci>
<fibonacci index="1">1</fibonacci>
<fibonacci index="2">1</fibonacci>
<fibonacci index="3">2</fibonacci>
<fibonacci index="4">3</fibonacci>
<fibonacci index="5">5</fibonacci>
<fibonacci index="6">8</fibonacci>
<fibonacci index="7">13</fibonacci>
<fibonacci index="8">21</fibonacci>
<fibonacci index="9">34</fibonacci>
<fibonacci index="10">55</fibonacci>
<fibonacci index="11">89</fibonacci>
<fibonacci index="12">144</fibonacci>
<fibonacci index="13">233</fibonacci>
<fibonacci index="14">377</fibonacci>
<fibonacci index="15">610</fibonacci>
<fibonacci index="16">987</fibonacci>
<fibonacci index="17">1597</fibonacci>
<fibonacci index="18">2584</fibonacci>
<fibonacci index="19">4181</fibonacci>
<fibonacci index="20">6765</fibonacci>
<fibonacci index="21">10946</fibonacci>
<fibonacci index="22">17711</fibonacci>
<fibonacci index="23">28657</fibonacci>
<fibonacci index="24">46368</fibonacci>
<fibonacci index="25">75025</fibonacci>
</Fibonacci_Numbers>

10
test/rexml/data/foo.xml Normal file
View file

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!DOCTYPE schema SYSTEM "foo.dtd" [
<!ATTLIST root-el
xmlns:human CDATA #FIXED "http://www.foo.com/human">
]>
<root-el xmlns="http://www.bar.com/doc"
xmlns:table="http://www.foo.com/table">
<human:leg>human leg</human:leg>
<table:leg>table leg</table:leg>
</root-el>

View file

@ -0,0 +1,156 @@
<form xmlns='http://www.w3.org/1999/xhtml'
enctype='application/x-www-form-urlencoded' class='rollover'
action='ModifyCampaign' method='POST'
onsubmit='return beforeRolloverSubmit(this, &apos;No campaigns selected.&apos;);'>
<a name='campaigns' shape='rect'/>
<tr bgcolor='#dbe6de'>
<th class='boxcolumn' rowspan='1' align='left' colspan='1'
width='1%'>
<script type='text/javascript'>document.write(" &lt;input
type\u003d\"checkbox\" name\u003d\"toggleAll\"
onclick\u003d\"rowToggleAll(this);\" title\u003d\"Select or
de-select all campaigns on this page\"&gt; ");</script>
</th>
<th bgcolor='#dbe6de' title='Sort by campaign name' nowrap='nowrap'
rowspan='1' align='left' colspan='1'>
<b>
<a href='CampaignSummary?campaignsummaryt=0%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>Campaign Name</a>
</b>
</th>
<th bgcolor='#dbe6de' title='Sort by campaign status'
nowrap='nowrap' rowspan='1' align='left' colspan='1'>
<a href='CampaignSummary?campaignsummaryt=1%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>Current Status</a>
</th>
<th bgcolor='#dbe6de'
title='Sort by daily budget (maximum spending per day)'
nowrap='nowrap' rowspan='1' align='right' colspan='1'>
<a href='CampaignSummary?campaignsummaryt=2%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>Current Budget</a>
<span style='white-space: nowrap'>
<a href='/support/bin/answer.py?answer=6312&amp;hl=en_US'
shape='rect' id='' onclick='return helpPopUp(this);' style=''
target='google_popup'>[?]</a>
</span>
</th>
<th bgcolor='#c6d7cf' title='Sort by clicks on your ads'
nowrap='nowrap' rowspan='1' align='right' colspan='1'>
<a href='CampaignSummary?campaignsummaryt=-3%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>Clicks</a>
<a href='CampaignSummary?campaignsummaryt=-3%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
shape='rect' style='text-decoration:none;'>
<img src='/select/images/sortdown.gif' border='0' alt=''/>
</a>
</th>
<th bgcolor='#dbe6de' title='Sort by ad impressions served'
nowrap='nowrap' rowspan='1' align='right' colspan='1'>
<a href='CampaignSummary?campaignsummaryt=4%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>Impr.</a>
</th>
<th bgcolor='#dbe6de' title='Sort by CTR (clickthrough rate)'
nowrap='nowrap' rowspan='1' align='right' colspan='1'>
<a href='CampaignSummary?campaignsummaryt=5%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>CTR</a>
</th>
<th bgcolor='#dbe6de' title='Sort by average cost per click (USD)'
nowrap='nowrap' rowspan='1' align='right' colspan='1'>
<a href='CampaignSummary?campaignsummaryt=6%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>Avg. CPC</a>
</th>
<th bgcolor='#dbe6de' class='' title='Sort by total cost (USD)'
nowrap='nowrap' rowspan='1' align='right' colspan='1'>
<a href='CampaignSummary?campaignsummaryt=8%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>Cost</a>
</th>
<th bgcolor='#dbe6de' title='Conversion Rate' nowrap='nowrap'
rowspan='1' align='right' colspan='1'>
<a href='CampaignSummary?campaignsummaryt=11%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>Conv. Rate</a>
</th>
<th bgcolor='#dbe6de' class='rightcolumn'
title='Cost per Conversion' nowrap='nowrap' rowspan='1'
align='right' colspan='1'>
<a href='CampaignSummary?campaignsummaryt=12%3Aa&amp;gsessionid=ezmXK9aaXnI#campaigns'
class='bluelink' shape='rect'>Cost/Conv.</a>
</th>
</tr>
<tr onmouseover='ron(3527627);' id='tr_3527627'
onmouseout='roff(3527627);'>
<td class='boxcolumn' rowspan='1' onclick='rowToggle(3527627);'
colspan='1'>
<input name='campaignid' type='checkbox' id='box_3527627'
value='3527627' onclick='toggleRow(this);'/>
</td>
<td rowspan='1' colspan='1'>
<a href='CampaignManagement?campaignid=3527627#a' shape='rect'>Test</a>
</td>
<td rowspan='1' colspan='1'>
<b>
<font size='-1' color='#b98b00'>Paused</font>
</b>
</td>
<td class='r' rowspan='1' colspan='1'>
<font color='#666666'>Test</font>
</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='' rowspan='1' align='right' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='rightcolumn' rowspan='1' align='right' colspan='1'>1</td>
</tr>
<tr onmouseover='ron(7680287);' id='tr_7680287'
onmouseout='roff(7680287);'>
<td class='boxcolumn' rowspan='1' onclick='rowToggle(7680287);'
colspan='1'>
<input name='campaignid' type='checkbox' id='box_7680287'
value='7680287' onclick='toggleRow(this);'/>
</td>
<td rowspan='1' colspan='1'>
<a href='CampaignManagement?campaignid=7680287#a' shape='rect'>Test</a>
</td>
<td rowspan='1' colspan='1'>
<b>
<font size='-1' color='#b98b00'>Paused</font>
</b>
</td>
<td class='r' rowspan='1' colspan='1'>
<font color='#666666'>Test</font>
</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='' rowspan='1' align='right' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='rightcolumn' rowspan='1' align='right' colspan='1'>1</td>
</tr>
<tr onmouseover='ron(6747347);' id='tr_6747347'
onmouseout='roff(6747347);'>
<td class='boxcolumn' rowspan='1' onclick='rowToggle(6747347);'
colspan='1'>
<input name='campaignid' type='checkbox' id='box_6747347'
value='6747347' onclick='toggleRow(this);'/>
</td>
<td rowspan='1' colspan='1'>
<a href='CampaignManagement?campaignid=6747347#a' shape='rect'>Test</a>
</td>
<td rowspan='1' colspan='1'>
<b>
<font size='-1' color='#b98b00'>Test</font>
</b>
</td>
<td class='r' rowspan='1' colspan='1'>
<font color='#666666'>Test</font>
</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='' rowspan='1' align='right' colspan='1'>1</td>
<td class='r' rowspan='1' colspan='1'>1</td>
<td class='rightcolumn' rowspan='1' align='right' colspan='1'>1</td>
</tr>
</form>

21
test/rexml/data/id.xml Normal file
View file

@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo (bar)>
<!ATTLIST foo id CDATA #IMPLIED>
<!ELEMENT bar (#PCDATA|cheese)*>
<!ATTLIST bar id ID #REQUIRED>
<!ELEMENT cheese (#PCDATA)>
<!ATTLIST cheese kind ID #IMPLIED>
]>
<foo id="foobar">
<bar id="fb1">
baz
<cheese kind="edam">gouda</cheese>
baz
<cheese kind="gouda">cheddar</cheese>
baz
</bar>
</foo>

View file

@ -0,0 +1,4 @@
<?xml version='1.0' encoding='ISO-8859-1'?>
<booh>
<image caption='andrè is nice'/>
</booh>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<body><p><span></span></p><div></div></body>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<hostname>
<val>2</val>
<attrlist>
<hostname>CE-A</hostname>
</attrlist>
</hostname>
<hostname>
<val>1</val>
<attrlist>
<hostname>CE-B</hostname>
</attrlist>
</hostname>
</Configuration>

11
test/rexml/data/lang.xml Normal file
View file

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<e1 xml:lang="hr">
<e2 xml:lang="en-US">
<e3/>
</e2>
<e2 xml:lang="hu">
<e3/>
<e3/>
<e3 xml:lang="es"/>
</e2>
</e1>

18
test/rexml/data/lang0.xml Normal file
View file

@ -0,0 +1,18 @@
<programming_languages>
<language oop='yes'>
<name>
Ruby
</name>
<creator>
Yukihiro Matsumoto
</creator>
</language>
<language oop='yes'>
<name>
Python
</name>
<creator>
Guido van Rossum
</creator>
</language>
</programming_languages>

View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<message>
<header>
<service>lookupformservice</service>
<connectionid>9</connectionid>
<appid>stammdaten</appid>
<action>new</action>
</header>
<body>
<data>
<items>
<item>
<name>iteminfo</name>
<value>ELE</value>
</item>
<item>
<name>parentinfo</name>
<value>Pruefgebiete</value>
</item>
<item>
<name>id</name>
<value>1</value>
</item>
</items>
</data>
</body>
</message>

View file

@ -0,0 +1,244 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<moreovernews>
<article code="13563275">
<url>http://c.moreover.com/click/here.pl?x13563273</url>
<headline_text>e-Commerce Operators Present Version 1.0 of the XML Standard</headline_text>
<source>StockAccess</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.stockaccess.com/index.html</document_url>
<harvest_time>Dec 24 2000 6:28AM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13560996">
<url>http://c.moreover.com/click/here.pl?x13560995</url>
<headline_text>W3C Publishes XML Protocol Requirements Document</headline_text>
<source>Xml</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.xml.com/</document_url>
<harvest_time>Dec 24 2000 12:22AM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13553522">
<url>http://c.moreover.com/click/here.pl?x13553521</url>
<headline_text>Prowler: Open Source XML-Based Content Management Framework</headline_text>
<source>Xml</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.xml.com/</document_url>
<harvest_time>Dec 23 2000 2:05PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13549014">
<url>http://c.moreover.com/click/here.pl?x13549013</url>
<headline_text>The Middleware Company Debuts Public Training Courses in Ejb, J2ee And Xml</headline_text>
<source>Java Industry Connection</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
<harvest_time>Dec 23 2000 12:15PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13544468">
<url>http://c.moreover.com/click/here.pl?x13544467</url>
<headline_text>Revised Working Draft for the W3C XML Information Set</headline_text>
<source>Xml</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.xml.com/</document_url>
<harvest_time>Dec 23 2000 5:50AM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13534837">
<url>http://c.moreover.com/click/here.pl?x13534836</url>
<headline_text>XML: Its The Great Peacemaker</headline_text>
<source>ZDNet</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.zdnet.com/intweek/</document_url>
<harvest_time>Dec 22 2000 9:05PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13533486">
<url>http://c.moreover.com/click/here.pl?x13533485</url>
<headline_text>Project eL - The XML Leningrad Codex Markup Project</headline_text>
<source>Xml</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.xml.com/</document_url>
<harvest_time>Dec 22 2000 8:34PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13533489">
<url>http://c.moreover.com/click/here.pl?x13533488</url>
<headline_text>XML Linking Language (XLink) and XML Base Specifications Issued as W3C Proposed Recommenda</headline_text>
<source>Xml</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.xml.com/</document_url>
<harvest_time>Dec 22 2000 8:34PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13533493">
<url>http://c.moreover.com/click/here.pl?x13533492</url>
<headline_text>W3C Releases XHTML Basic Specification as a W3C Recommendation</headline_text>
<source>Xml</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.xml.com/</document_url>
<harvest_time>Dec 22 2000 8:34PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13521835">
<url>http://c.moreover.com/click/here.pl?x13521827</url>
<headline_text>Java, Xml And Oracle9i(TM) Make A Great Team</headline_text>
<source>Java Industry Connection</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
<harvest_time>Dec 22 2000 3:21PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13512020">
<url>http://c.moreover.com/click/here.pl?x13511233</url>
<headline_text>Competing initiatives to vie for security standard</headline_text>
<source>ZDNet</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.zdnet.com/eweek/filters/news/</document_url>
<harvest_time>Dec 22 2000 10:54AM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13492401">
<url>http://c.moreover.com/click/here.pl?x13492397</url>
<headline_text>Oracle Provides Developers with Great Xml Reading This Holiday Season</headline_text>
<source>Java Industry Connection</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
<harvest_time>Dec 21 2000 8:08PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13491296">
<url>http://c.moreover.com/click/here.pl?x13491292</url>
<headline_text>XML as the great peacemaker - Extensible Markup Language Accomplished The Seemingly Impossible This Year: It B</headline_text>
<source>Hospitality Net</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.hospitalitynet.org/news/list.htm?c=2000</document_url>
<harvest_time>Dec 21 2000 7:45PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13484761">
<url>http://c.moreover.com/click/here.pl?x13484758</url>
<headline_text>XML as the great peacemaker</headline_text>
<source>CNET</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://news.cnet.com/news/0-1003.html?tag=st.ne.1002.dir.1003</document_url>
<harvest_time>Dec 21 2000 4:41PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13480897">
<url>http://c.moreover.com/click/here.pl?x13480896</url>
<headline_text>COOP Switzerland Selects Mercator as Integration Platform</headline_text>
<source>Stockhouse Canada</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.stockhouse.ca/news/</document_url>
<harvest_time>Dec 21 2000 1:55PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13471024">
<url>http://c.moreover.com/click/here.pl?x13471023</url>
<headline_text>Competing XML Specs Move Toward a Union</headline_text>
<source>Internet World</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://www.internetworld.com/</document_url>
<harvest_time>Dec 21 2000 11:14AM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13452281">
<url>http://c.moreover.com/click/here.pl?x13452280</url>
<headline_text>Next-generation XHTML stripped down for handhelds</headline_text>
<source>CNET</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://news.cnet.com/news/0-1005.html?tag=st.ne.1002.dir.1005</document_url>
<harvest_time>Dec 20 2000 9:11PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13451791">
<url>http://c.moreover.com/click/here.pl?x13451789</url>
<headline_text>Xml Powers Oracle9i(TM) Dynamic Services</headline_text>
<source>Java Industry Connection</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
<harvest_time>Dec 20 2000 9:05PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13442098">
<url>http://c.moreover.com/click/here.pl?x13442097</url>
<headline_text>XML DOM reference guide</headline_text>
<source>ASPWire</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://aspwire.com/</document_url>
<harvest_time>Dec 20 2000 6:26PM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
<article code="13424118">
<url>http://c.moreover.com/click/here.pl?x13424117</url>
<headline_text>Repeat/Xqsite And Bowstreet Team to Deliver Integrated Xml Solutions</headline_text>
<source>Java Industry Connection</source>
<media_type>text</media_type>
<cluster>moreover...</cluster>
<tagline> </tagline>
<document_url>http://industry.java.sun.com/javanews/more/hotnews/</document_url>
<harvest_time>Dec 20 2000 9:04AM</harvest_time>
<access_registration> </access_registration>
<access_status> </access_status>
</article>
</moreovernews>

6850
test/rexml/data/much_ado.xml Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<foo:a xmlns:foo="http://fooNamespace/">
<b>
<c>Hello</c>
</b>
<foo:d>
<foo:e>Hey</foo:e>
</foo:d>
<bar:f xmlns:bar="http://barNamespace/">
<bar:g>Hey2</bar:g>
</bar:f>
<alias:x xmlns:alias="http://fooNamespace/">
<alias:y>Hey3</alias:y>
</alias:x>
</foo:a>

67
test/rexml/data/nitf.xml Normal file
View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<nitf>
<!-- Example of markup of URLs (at the bottom of the story) -->
<head>
<meta name="ap-cycle" content="AP"/>
<meta name="ap-online-code" content="1700"/>
<meta name="ap-company" content="CO:Media Metrix Inc;TS:MMXI;IG:SVC;"/>
<meta name="ap-routing" content="ENTITLEMENTS,pfONLINE,pf1700"/>
<meta name="ap-format" content="bx"/>
<meta name="ap-category" content="f"/>
<meta name="ap-selector" content="-----"/>
<meta name="ap-transref" content="V0347"/>
<docdata>
<doc-id regsrc="AP" id-string="D76UIMO80"/>
<urgency ed-urg="7"/>
<date.issue norm="20000911T185842Z"/>
<du-key key="Napster Traffic"/>
<doc.copyright holder="(AP)"/>
</docdata>
</head>
<body>
<body.head>
<hedline>
<hl1>Use of Napster Quadruples</hl1>
</hedline>
<byline>By PETER SVENSSON
<byttl>AP Business Writer</byttl>
</byline>
<distributor>The Associated Press</distributor>
<dateline>
<location>NEW YORK</location>
</dateline>
</body.head>
<body.content>
<block>
<p>Despite the uncertain legality of the Napster online music-sharing service, the number of people
using it more than quadrupled in just five months, Media Metrix said Monday.</p>
<p>That made Napster the fastest-growing software application ever recorded by the Internet research
company.</p>
<p>From 1.1 million home users in the United States in February, the first month Media Metrix
tracked the application, Napster use rocketed to 4.9 million users in July.</p>
<p>That represents 6 percent of U.S. home PC users who have modems, said Media Metrix, which pays
people to install monitoring software on their computers.</p>
<p>It estimates total usage from a panel of about 50,000 people in the United States.</p>
<p>Napster was also used at work by 887,000 people in July, Media Metrix said.</p>
<p>Napster Inc. has been sued by the recording industry for allegedly enabling copyright
infringement. The federal government weighed in on the case Friday, saying the service is not protected
under a key copyright law, as the San Mateo, Calif., company claims.</p>
<p>Bruce Ryon, head of Media Metrix&apos;s New Media Group, said Napster was used by &quot;the full spectrum of PC users, not just the youth with time on their hands and a passion for music.&quot;</p>
<p>The Napster program allows users to copy digital music files from the hard drives of other
users over the Internet.</p>
<p>Napster Inc. said last week that 28 million people had downloaded its program. It does not reveal
its own figures for how many people actually use the software.</p>
<p>Because the program connects to the company&apos;s computers over the Internet every time
it is run, Napster Inc. can track usage exactly.</p>
<p>__</p>
<p>On the Net:</p>
<p><a href="http://www.napster.com">
http://www.napster.com</a></p>
<p><a href="http://www.mediametrix.com">
http://www.mediametrix.com</a></p>
</block>
</body.content>
</body>
</nitf>

View file

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<numbers>
<set>
<nr>3</nr>
<nr>24</nr>
<nr>55</nr>
<nr>11</nr>
<nr>2</nr>
<nr>-3</nr>
</set>
<set>
<nr value="66"/>
<nr value="123"/>
<nr value="55"/>
<nr value="9999"/>
</set>
</numbers>

File diff suppressed because it is too large Load diff

13
test/rexml/data/pi.xml Normal file
View file

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<foo>
<?cheese is tasty?>
<bar>
<baz/>
<cheese/>
<baz/>
<?toast is tasty?>
<cheese/>
<baz/>
</bar>
<?cheese is gooey?>
</foo>

6
test/rexml/data/pi2.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0"?>
<a>
<b>foo</b>
<?toc order-by="x"?>
<c>bar</c>
</a>

View file

@ -0,0 +1 @@
<Project id="17" Name="dave test" Deprecated="false"><Creator User="etools" Date="10/24/00 10:54 AM"></Creator><LastModifier User="Default" Date="Fri Jun 22 14:01:54 PDT 2001"></LastModifier><Description>tool testing</Description><Purpose> </Purpose><Datasets><link name="Test data 1" idref="18"></link><link name="veg plot data" idref="21"></link></Datasets></Project>

View file

@ -0,0 +1,2 @@
<?xml version="1.0" ?>
<root><a>a</a><b>b</b><c><d>d</d></c></root>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<g>
<f a="é" />
</g>

BIN
test/rexml/data/t63-1.xml Normal file

Binary file not shown.

2828
test/rexml/data/t63-2.svg Normal file

File diff suppressed because it is too large Load diff

31
test/rexml/data/t75.xml Normal file
View file

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="ISO-8859-1"?><?pos="3"?>
<!-- generated by hnb 1.9.17 (http://hnb.sourceforge.net) -->
<!DOCTYPE tree[
<!ELEMENT tree (node*)>
<!ELEMENT data (#PCDATA)> <!-- (max 4096 bytes long) -->
<!ELEMENT node (data?,node*)>
<!ATTLIST node done (yes|no) #IMPLIED
type CDATA #IMPLIED
>]>
<tree>
<node done="no" type="todo"><data>Next_Actions</data>
<node done="no" type="todo"><data>@class</data></node>
<node done="no" type="todo"><data>@agenda</data>
<node done="yes" type="todo"><data>this is something I&apos;d like to do</data></node>
</node>
<node done="no" type="todo"><data>@dorm</data>
<node done="no" type="todo"><data>clean room</data></node>
</node>
<node done="no" type="todo"><data>@computer</data>
<node done="no" type="todo"><data>Write general makefile for cs projects</data></node>
<node done="no" type="todo"><data>Set up bash podder</data></node>
</node>
<node done="no" type="todo"><data>@errands</data>
<node done="no" type="todo"><data>Purchase geo lab book</data></node>
</node>
<node done="no" type="todo"><data>@dublin</data></node>
</node>
<node><data>projects</data></node>
</tree>

View file

@ -0,0 +1,683 @@
<?xml version="1.0" encoding="UTF-8"?>
<tests xmlns:var="http://jaxen.org/test-harness/var">
<!-- test for jaxen-24 -->
<document url="xml/jaxen24.xml">
<context select="/body/div">
<test select="preceding::*[1]" count="1"/>
<valueOf select="local-name(preceding::*[1])">span</valueOf>
</context>
<!-- jaxen-58 -->
<context select="/">
<test select="//preceding::x" count="0"/>
<test select="//following::x" count="0"/>
<test select="/descendant::*/preceding::x" count="0"/>
<test select="/descendant::node()/preceding::x" count="0"/>
</context>
</document>
<!-- test for jaxen-3 -->
<document url="xml/simple.xml">
<context select="/">
<valueOf select="string()">abd</valueOf>
</context>
<context select="/root">
<valueOf select="string()">abd</valueOf>
</context>
<context select="/root/a">
<valueOf select="string()">a</valueOf>
</context>
<context select="/root/c">
<valueOf select="string()">d</valueOf>
</context>
</document>
<!-- test for jaxen-3 -->
<document url="xml/jaxen3.xml">
<context select="/">
<test select="/Configuration/hostname/attrlist/hostname[. = 'CE-A'] " count="1"/>
</context>
</document>
<!-- parser test cases all of which should fail-->
<document url="xml/numbers.xml">
<context select="/">
<!-- repeated xpaths, jaxen-35 -->
<test exception="true" select="/numbers numbers" count="0"/>
<!-- invalid xpath, jaxen-34 -->
<test exception="true" select="/a/b[c > d]efg" count="0"/>
<!-- invalid xpath, jaxen-27 -->
<test exception="true" select="/inv/child::" count="0"/>
<!-- invalid xpath, jaxen-26 -->
<!--
<test exception="true" select="/invoice/@test[abcd" count="0"/>
<test exception="true" select="/invoice/@test[abcd > x" count="0"/>
<test exception="true" select="string-length('a" count="0"/>
<test exception="true" select="/descendant::()" count="0"/>
<test exception="true" select="(1 + 1" count="0"/>
-->
</context>
</document>
<!-- test cases for the use of underscores in names -->
<document url="xml/underscore.xml">
<context select="/">
<test select="/root/@a" count="1"/>
<test select="/root/@_a" count="1"/>
<test select="/root/b" count="1"/>
<test select="/root/_b" count="1"/>
<valueOf select="/root/@a">1</valueOf>
<valueOf select="/root/@_a">2</valueOf>
<valueOf select="/root/b">1</valueOf>
<valueOf select="/root/_b">2</valueOf>
</context>
</document>
<!-- test cases for the use of = with nodesets -->
<document url="xml/web.xml">
<context select="/">
<valueOf select="/web-app/servlet/servlet-name = 'file'">true</valueOf>
<valueOf select="/web-app/servlet/servlet-name = 'snoop'">true</valueOf>
</context>
</document>
<document url="xml/numbers.xml">
<context select="/">
<valueOf select="/numbers/set/nr = '-3'">true</valueOf>
<valueOf select="/numbers/set/nr = -3">true</valueOf>
<valueOf select="/numbers/set/nr = 24">true</valueOf>
<valueOf select="/numbers/set/nr/@value = '9999'">true</valueOf>
<valueOf select="/numbers/set/nr/@value = 9999.0">true</valueOf>
<valueOf select="/numbers/set/nr/@value = 66">true</valueOf>
</context>
</document>
<!-- test basic math... -->
<document url="xml/numbers.xml">
<context select="/">
<valueOf select="(8 * 2 + 1) = 17">true</valueOf>
<valueOf select="(1 + 8 * 2) = 17">true</valueOf>
<valueOf select="(7 - 3 + 1) = 5">true</valueOf>
<valueOf select="(8 - 4 + 5 - 6) = 3">true</valueOf>
<!-- left-assoc tests, comments show WRONG evaluation -->
<!-- 3 - 2 - 1 != 2 -->
<valueOf select="3 - 2 - 1">0</valueOf>
<!-- 8 div 4 div 2 != 4 -->
<valueOf select="8 div 4 div 2">1</valueOf>
<!-- 3 mod 5 mod 7 != 1 -->
<valueOf select="3 mod 7 mod 5">3</valueOf>
<!-- 1=(2=2) is true-->
<valueOf select="1 = 2 = 2">false</valueOf>
<!-- 2!=(3!=1) => 2!=1 => true, (2!=3)!=1 => 1!=1 => false -->
<valueOf select="2 != 3 != 1">false</valueOf>
<!-- 3 > (2 > 1) is true -->
<valueOf select="3 &gt; 2 &gt; 1">false</valueOf>
<!-- 3 >= (2 >= 2) is true -->
<valueOf select="3 &gt;= 2 &gt;= 2">false</valueOf>
<!-- 1 < (2 < 3) is false -->
<valueOf select="1 &lt; 2 &lt; 3">true</valueOf>
<!-- 0 <= (2 <= 3) is true -->
<valueOf select="2 &lt;= 2 &lt;= 3">true</valueOf>
</context>
</document>
<!-- test cases for preceding axis with different node types -->
<document url="xml/pi2.xml">
<context select="/a/c">
<test select="//processing-instruction()" count="1"/>
<test select="preceding-sibling::*" count="1"/>
<test select="preceding-sibling::node()" count="5"/>
<test select="preceding-sibling::*[1]" count="1"/>
<test select="preceding-sibling::processing-instruction()" count="1"/>
<valueOf select="preceding-sibling::processing-instruction()">order-by="x"</valueOf>
<valueOf select="preceding-sibling::*[1]">foo</valueOf>
<valueOf select="preceding-sibling::node()[2]">order-by="x"</valueOf>
</context>
</document>
<document url="xml/id.xml">
<context select="/"
var:foobar="foobar"
var:foo="foo">
<valueOf select="$foobar">foobar</valueOf>
<test select="/foo[@id=$foobar]" count="1"/>
<test select="/foo[@id='$foobar']" count="0"/>
<test select="/foo[concat($foo, 'bar')=@id]" count="1"/>
<test select="CD_Library/artist[@name=$artist]" count="0"/>
</context>
</document>
<document url="xml/id.xml">
<context select="/">
<!-- attributes have a parent: their element -->
<test select="/foo/@id/parent::foo" count="1"/>
</context>
<!-- attributes can also be used as context nodes -->
<context select="/foo/@id">
<test select="parent::foo" count="1"/>
</context>
</document>
<document url="xml/pi.xml">
<context select="/">
<test select="//processing-instruction()" count="3"/>
<test select="//processing-instruction('cheese')" count="2"/>
<test select="//processing-instruction('toast')" count="1">
<valueOf select="string()">is tasty</valueOf>
</test>
</context>
</document>
<!-- test evaluate() extension function -->
<document url="xml/evaluate.xml">
<context select="/">
<test select="evaluate('//jumps/*')" count="3"/>
<test select="evaluate('//jumps/object/dog')" count="1"/>
<test select="evaluate('//jumps/object')/evaluate" count="0"/>
<test select="evaluate('//jumps/object')/dog" count="1"/>
<test select="evaluate('//jumps/*')/dog" count="1"/>
<test select="//metatest[ evaluate(@select) = . ]" count="1"/>
</context>
</document>
<document url="xml/numbers.xml">
<context select="/numbers/set[1]">
<test select="*[-3 = .]" count="1"/>
<valueOf select="54 &lt; *">true</valueOf>
<valueOf select="55 &lt;= *">true</valueOf>
<valueOf select="69 &lt; *">false</valueOf>
<valueOf select="-2 &gt; *">true</valueOf>
<valueOf select="-3 &gt;= *">true</valueOf>
<valueOf select="-4 &gt;= *">false</valueOf>
</context>
<!-- TODO
This context should work, but needs a fixed version of saxpath to parse the right-hand side
of the greater-than expression.
<context select="/numbers/set[2]">
<valueOf select="1 &gt; nr/@value">false</valueOf>
<valueOf select="55 &gt; nr/@value">false</valueOf>
<valueOf select="55 &gt;= nr/@value">true</valueOf>
<valueOf select="1000000 &gt; nr/@value">true</valueOf>
</context>
-->
</document>
<!-- test sibling axes -->
<document url="xml/axis.xml">
<context select="/root">
<test select="preceding-sibling::*" count="0"/>
</context>
<context select="/root/a/a.3">
<test select="preceding::*" count="2"/>
</context>
<context select="/root/a/a.3">
<test select="preceding-sibling::*" count="2"/>
</context>
<context select="/">
<valueOf select="name(/root/a/a.3/preceding-sibling::*[1])">a.2</valueOf>
<valueOf select="name(/root/a/a.3/preceding-sibling::*[2])">a.1</valueOf>
</context>
<context select="/">
<valueOf select="name(/root/a/a.3/following-sibling::*[1])">a.4</valueOf>
<valueOf select="name(/root/a/a.3/following-sibling::*[2])">a.5</valueOf>
</context>
</document>
<document url="xml/web.xml">
<context select="/">
<valueOf select="/web-app/servlet[1]/servlet-name">snoop</valueOf>
<valueOf select="/web-app/servlet[1]/servlet-name/text()">snoop</valueOf>
<valueOf select="/web-app/servlet[2]/servlet-name">file</valueOf>
<valueOf select="/web-app/servlet[2]/servlet-name/text()">file</valueOf>
</context>
<context select="/web-app/servlet[1]">
<valueOf select="servlet-name">snoop</valueOf>
<valueOf select="servlet-name/text()">snoop</valueOf>
</context>
<context select="/web-app/servlet[2]/servlet-name">
<test select="preceding::*" count="3"/>
</context>
<context select="/web-app/servlet[2]/servlet-name">
<test select="following::*" count="13"/>
</context>
</document>
<!-- test name -->
<document url="xml/web.xml">
<context select="/">
<test select="*" count="1">
<valueOf select="name()">web-app</valueOf>
</test>
<!-- NOTE that the child::node() tests only work if the
XML document does not comments or PIs
-->
<test select="./*" count="1">
<valueOf select="name()">web-app</valueOf>
</test>
<test select="child::*" count="1">
<valueOf select="name()">web-app</valueOf>
</test>
<test select="/*" count="1">
<valueOf select="name()">web-app</valueOf>
</test>
<test select="/child::node()" count="1">
<valueOf select="name(.)">web-app</valueOf>
</test>
<test select="child::node()" count="1">
<valueOf select="name(.)">web-app</valueOf>
</test>
<!-- empty names -->
<valueOf select="name()"></valueOf>
<valueOf select="name(.)"></valueOf>
<valueOf select="name(parent::*)"></valueOf>
<valueOf select="name(/)"></valueOf>
<valueOf select="name(/.)"></valueOf>
<valueOf select="name(/self::node())"></valueOf>
<!-- name of root elemet -->
<valueOf select="name(node())">web-app</valueOf>
<valueOf select="name(/node())">web-app</valueOf>
<valueOf select="name(/*)">web-app</valueOf>
<valueOf select="name(/child::*)">web-app</valueOf>
<valueOf select="name(/child::node())">web-app</valueOf>
<valueOf select="name(/child::node())">web-app</valueOf>
<valueOf select="name(child::node())">web-app</valueOf>
<valueOf select="name(./*)">web-app</valueOf>
<valueOf select="name(*)">web-app</valueOf>
</context>
<context select="/*">
<!-- empty names -->
<valueOf select="name(..)"></valueOf>
<valueOf select="name(parent::node())"></valueOf>
<valueOf select="name(parent::*)"></valueOf>
<!-- name of root elemet -->
<valueOf select="name()">web-app</valueOf>
<valueOf select="name(.)">web-app</valueOf>
<valueOf select="name(../*)">web-app</valueOf>
<valueOf select="name(../child::node())">web-app</valueOf>
</context>
</document>
<!-- test predicates -->
<document url="xml/nitf.xml">
<context select="/nitf/head/docdata">
<test select="doc-id[@regsrc='AP' and @id-string='D76UIMO80']" count="1"/>
</context>
<context select="/nitf/head">
<test select="meta[@name='ap-cycle']" count="1"/>
<test select="meta[@content='AP']" count="1"/>
<test select="meta[@name and @content]" count="8"/>
<test select="meta[@name='ap-cycle' and @content='AP']" count="1"/>
<test select="meta[@name != 'ap-cycle']" count="7"/>
</context>
<context select="/">
<test select="/nitf/head/meta[@name='ap-cycle']" count="1"/>
<test select="/nitf/head/meta[@content='AP']" count="1"/>
<test select="/nitf/head/meta[@name and @content]" count="8"/>
<test select="/nitf/head/meta[@name='ap-cycle' and @content='AP']" count="1"/>
<test select="/nitf/head/meta[@name != 'ap-cycle']" count="7"/>
</context>
</document>
<document url="xml/moreover.xml">
<context select="/">
<test select="/child::node()" count="1"/>
<test select="/*" count="1"/>
<test select="/*/article" count="20"/>
<test select="//*" count="221"/>
<test select="//*[local-name()='article']" count="20"/>
<test select="//article" count="20"/>
<test select="/*/*[@code]" count="20"/>
<test select="/moreovernews/article[@code='13563275']" count="1"/>
<test select="/moreovernews/article[@code='13563275']">
<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
</test>
<test select="/*/article[@code='13563275']">
<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
</test>
<test select="//article[@code='13563275']">
<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
</test>
<test select="//*[@code='13563275']">
<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
</test>
<test select="/child::node()/child::node()[@code='13563275']">
<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
</test>
<test select="/*/*[@code='13563275']">
<valueOf select="url">http://c.moreover.com/click/here.pl?x13563273</valueOf>
</test>
</context>
</document>
<!-- test other node types-->
<document url="xml/contents.xml">
<context select="/">
<test select="processing-instruction()" count="3"/>
<test select="/processing-instruction()" count="3"/>
<test select="/comment()" count="1"/>
<test select="comment()" count="1"/>
<test select="/child::node()/comment()" count="2"/>
<test select="/*/comment()" count="2"/>
<test select="//comment()" count="3"/>
</context>
</document>
<!-- test positioning -->
<document url="xml/fibo.xml">
<context select="/">
<test select="/*/fibonacci[position() &lt; 10]" count="9"/>
<valueOf select="sum(//fibonacci)">196417</valueOf>
<valueOf select="sum(//fibonacci/@index)">325</valueOf>
<valueOf select="/*/fibonacci[2]">1</valueOf>
<valueOf select="/*/fibonacci[ count(/*/fibonacci) ]">75025</valueOf>
<valueOf select="/*/fibonacci[ count(/*/fibonacci) - 1 ]">46368</valueOf>
</context>
</document>
<!-- test number functions -->
<!-- test Axes -->
<document url="xml/web.xml">
<context select="/">
<test select="descendant-or-self::*" count="19"/>
<test select="descendant::*" count="19"/>
<test select="/descendant::*" count="19"/>
<test select="/descendant-or-self::*" count="19"/>
<test select="/descendant::servlet" count="2"/>
<test select="/descendant-or-self::servlet" count="2"/>
<test select="descendant-or-self::servlet" count="2"/>
<test select="descendant::servlet" count="2"/>
<test select="/*/servlet" count="2"/>
<valueOf select="count(/*/servlet)">2</valueOf>
<test select="//servlet" count="2"/>
<valueOf select="count(//servlet)">2</valueOf>
</context>
<context select="/web-app">
<test select="/descendant::servlet" count="2"/>
<test select="/descendant-or-self::servlet" count="2"/>
<test select="descendant-or-self::servlet" count="2"/>
<test select="descendant::servlet" count="2"/>
</context>
</document>
<document url="xml/much_ado.xml">
<context select="/">
<test select="/descendant::ACT" count="5"/>
<test select="descendant::ACT" count="5"/>
<valueOf select="/PLAY/TITLE">Much Ado about Nothing</valueOf>
<valueOf select="2+2">4</valueOf>
<valueOf select="5 * 4 + 1">21</valueOf>
<valueOf select="count(descendant::ACT)">5</valueOf>
<valueOf select="10 + count(descendant::ACT) * 5">35</valueOf>
<valueOf select="(10 + count(descendant::ACT)) * 5">75</valueOf>
</context>
<context select="/PLAY/ACT[2]/SCENE[1]">
<test select="/descendant::ACT" count="5"/>
<test select="../../descendant::ACT" count="5"/>
<test select="/PLAY/ACT[2]/SCENE[1]/descendant::SPEAKER" count="141"/>
<test select="descendant::SPEAKER" count="141"/>
<valueOf select="count(descendant::*)+1">646</valueOf>
<valueOf select="count(descendant::SPEAKER)+1">142</valueOf>
<valueOf select="count(ancestor::*)">2</valueOf>
<valueOf select="count(ancestor::PLAY)">1</valueOf>
<valueOf select="count(ancestor-or-self::*)">3</valueOf>
<valueOf select="count(ancestor-or-self::PLAY)">1</valueOf>
<valueOf select="5+count(ancestor::*)-1">6</valueOf>
</context>
<context select="/">
<!-- Test correct predicate application -->
<valueOf select="count(/PLAY/ACT/SCENE[1])">5</valueOf>
</context>
</document>
<!-- test axis node ordering -->
<document url="xml/web.xml">
<context select="/">
<!-- Reported as Jira issue JAXEN-24 -->
<test select="//servlet-mapping/preceding::*[1][name()='description']" count="1"/>
<test select="/web-app/servlet//description/following::*[1][name()='servlet-mapping']" count="1"/>
<test select="/web-app/servlet//description/following::*[2][name()='servlet-name']" count="1"/>
</context>
</document>
<!-- test document function -->
<document url="xml/text.xml">
<context select="/">
<test select="document('xml/web.xml')" count="1">
<valueOf select="/web-app/servlet[1]/servlet-name">snoop</valueOf>
<valueOf select="/web-app/servlet[1]/servlet-name/text()">snoop</valueOf>
</test>
<valueOf select="document('xml/web.xml')/web-app/servlet[1]/servlet-name">snoop</valueOf>
</context>
<!-- Test to check if the context changes when an extension function is used.
First test is an example, second is the actual test.
-->
<context select="/foo/bar/cheese[1]">
<valueOf select="concat(./@id,'foo',@id)">3foo3</valueOf>
<valueOf select="concat(./@id,document('xml/web.xml')/web-app/servlet[1]/servlet-name,./@id)">3snoop3</valueOf>
</context>
</document>
<document url="xml/message.xml">
<context select="/">
<valueOf select="/message/body/data/items/item[name/text()='parentinfo']/value">Pruefgebiete</valueOf>
<valueOf select="document('xml/message.xml')/message/body/data/items/item[name/text()='parentinfo']/value">Pruefgebiete</valueOf>
</context>
</document>
<document url="xml/simple.xml">
<!-- test behaviour of AbsoluteLocationPath -->
<context select="/root/a">
<valueOf select="concat( ., /root/b )">ab</valueOf>
<valueOf select="concat( ../b, . )">ba</valueOf>
<valueOf select="concat( /root/b, . )">ba</valueOf>
<valueOf select="concat( /root/c/d, ../b )">db</valueOf>
</context>
<!-- test the translate() function -->
<context select="/">
<valueOf select="translate( '', '', '' )"></valueOf>
<valueOf select="translate( 'abcd', '', '' )">abcd</valueOf>
<valueOf select="translate( 'abcd', 'abcd', 'abcd' )">abcd</valueOf>
<valueOf select="translate( 'abcd', 'dcba', 'dcba' )">abcd</valueOf>
<valueOf select="translate( 'abcd', 'abcd', 'dcba' )">dcba</valueOf>
<valueOf select="translate( 'abcd', 'abcd', 'ab' )">ab</valueOf>
<valueOf select="translate( 'abcd', 'cdab', 'cd' )">cd</valueOf>
<valueOf select="translate( 'abcd', 'acbd', 'xy' )">xy</valueOf>
<valueOf select="translate( 'abcd', 'abcdb', 'abcdb' )">abcd</valueOf>
<valueOf select="translate( 'abcd', 'abcd', 'abcdb' )">abcd</valueOf>
</context>
<context select="/">
<valueOf select="substring('12345', 1.5, 2.6)">234</valueOf>
<valueOf select="substring('12345', 0, 3)">12</valueOf>
<valueOf select="substring('12345', 0 div 0, 3)"></valueOf>
<valueOf select="substring('12345', 1, 0 div 0)"></valueOf>
<valueOf select="substring('12345', -42, 1 div 0)">12345</valueOf>
<valueOf select="substring('12345', -1 div 0, 1 div 0)"></valueOf>
<valueOf select="substring('12345', 3)">345</valueOf>
<valueOf select="substring('12345',1,15)">12345</valueOf>
</context>
<!-- Some tests for the normalize-space() function -->
<context select="/">
<valueOf select="normalize-space(' abc ')">abc</valueOf>
<valueOf select="normalize-space(' a b c ')">a b c</valueOf>
<valueOf select="normalize-space(' a &#x0d; b &#x0a; c ')">a b c</valueOf>
<!-- Next test case addresses issue JAXEN-22 -->
<valueOf select="normalize-space(' ')"></valueOf>
<!-- Next test case addresses issue JAXEN-29 -->
<valueOf select="normalize-space('')"></valueOf>
</context>
</document>
<!-- test cases for String extension functions -->
<document url="xml/web.xml">
<context select="/web-app/servlet[1]">
<valueOf select="upper-case( servlet-class )">SNOOPSERVLET</valueOf>
<valueOf select="lower-case( servlet-class )">snoopservlet</valueOf>
<valueOf select="upper-case( servlet-class, 'fr' )">SNOOPSERVLET</valueOf>
<valueOf select="upper-case( servlet-class, 'fr-CA' )">SNOOPSERVLET</valueOf>
<valueOf select="upper-case( servlet-class, 'es-ES-Traditional_WIN' )">SNOOPSERVLET</valueOf>
<valueOf select="ends-with( servlet-class, 'Servlet' )">true</valueOf>
<valueOf select="ends-with( servlet-class, 'S' )">false</valueOf>
</context>
</document>
<!-- test cases for the lang() function -->
<document url="xml/lang.xml">
<context select="/">
<test select="/e1/e2[lang('hr')]" count="0"/>
<test select="/e1/e2/e3[lang('en')]" count="1"/>
<test select="/e1/e2/e3[lang('en-US')]" count="1"/>
<test select="/e1/e2/e3[lang('en-GB')]" count="0"/>
<test select="/e1/e2/e3[lang('hu')]" count="2"/>
<test select="/e1/e2/e3[lang('hu-HU')]" count="0"/>
<test select="/e1/e2/e3[lang('es')]" count="1"/>
<test select="/e1/e2/e3[lang('es-BR')]" count="0"/>
</context>
</document>
<!-- test namespace -->
<document url="xml/namespaces.xml">
<context select="/"
xmlns:foo="http://fooNamespace/"
xmlns:voo="http://fooNamespace/"
xmlns:bar="http://barNamespace/"
xmlns:alias="http://fooNamespace/">
<test select="/*" count="1"/>
<test select="/foo:a" count="1"/>
<test select="/foo:a/b" count="1"/>
<test select="/voo:a/b/c" count="1"/>
<test select="/voo:a/bar:f" count="1"/>
<test select="/*[namespace-uri()='http://fooNamespace/' and local-name()='a']" count="1"/>
<test select="/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']" count="1"/>
<test select="/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']/*[local-name()='y' and namespace-uri()='http://fooNamespace/']" count="1"/>
</context>
<!-- the prefix here and in the document have no relation; it's their
namespace-uri binding that counts -->
<context select="/" xmlns:foo="http://somethingElse/">
<test select="/foo:a/b/c" count="0"/>
</context>
<context select="/"
xmlns:foo="http://fooNamespace/"
xmlns:bar="http://barNamespace/"
xmlns:alias="http://fooNamespace/">
<valueOf select="/foo:a/b/c">Hello</valueOf>
<valueOf select="/foo:a/foo:d/foo:e">Hey</valueOf>
<valueOf select="/foo:a/alias:x/alias:y">Hey3</valueOf>
<valueOf select="/foo:a/foo:x/foo:y">Hey3</valueOf>
<valueOf select="/*[local-name()='a' and namespace-uri()='http://fooNamespace/']/*[local-name()='x' and namespace-uri()='http://fooNamespace/']/*[local-name()='y' and namespace-uri()='http://fooNamespace/']">Hey3</valueOf>
</context>
</document>
<document url="xml/defaultNamespace.xml">
<context select="/">
<!-- NOTE: /a/b/c selects elements in no namespace only! -->
<test select="/a/b/c" count="0"/>
<!--
The following test uses an unbound prefix 'x' and should throw an exception.
Addresses issue JAXEN-18.
Turns out this isn't really tested as the test didn't fail when the exception wasn't thrown.
<test select="/x:a/x:b/x:c" count="0" exception="true"/>
-->
</context>
<context select="/"
xmlns:dummy="http://dummyNamespace/">
<test select="/dummy:a/dummy:b/dummy:c" count="1"/>
</context>
</document>
<document url="xml/text.xml">
<context select="/">
<test select="/foo/bar/text()" count="3"/>
<valueOf select="normalize-space(/foo/bar/text())">baz</valueOf>
</context>
</document>
<document url="xml/testNamespaces.xml">
<context select="/">
<!-- the root is not an element, so no namespaces -->
<test select="namespace::*" count="0" debug="off"/>
<test select="/namespace::*" count="0" debug="off"/>
<test select="/Template/Application1/namespace::*" count="3" debug="off"/>
<test select="/Template/Application2/namespace::*" count="3" debug="off"/>
<test select="//namespace::*" count="25" debug="off"/>
</context>
<!--
<context select="/Template/Application1">
<test select="namespace::*" count="3" debug="off"/>
<test select="/namespace::*" count="0" debug="off"/>
<test select="/Template/Application1/namespace::*" count="3" debug="off"/>
<test select="/Template/Application2/namespace::*" count="3" debug="off"/>
<test select="//namespace::*" count="25" debug="off"/>
<test select="//namespace::xplt" count="8" debug="off"/>
<test xmlns:somethingelse="http://www.xxxx.com/"
select="//namespace::somethingelse" count="0" debug="off"/>
</context>
-->
</document>
<document url="xml/testNamespaces.xml">
<context select="/">
<!-- namespace nodes have their element as their parent -->
<test select="/Template/namespace::xml/parent::Template" count="1"/>
</context>
<!-- namespace nodes can also be used as context nodes -->
<context select="/Template/namespace::xml">
<test select="parent::Template" count="1"/>
</context>
</document>
</tests>

View file

@ -0,0 +1,369 @@
<stylesheet xmlns="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:var="http://jaxen.org/test-harness/var">
<!-- this is what I used to generate XPathTestBase. After generating I fixed the illegal strings (its quicker
than fixing the xsl for that few errors) and reformatted the code. Its unlikely this code will be needed
again, its just in cvs for completeness -->
<output method="text"/>
<template match="/">
<text>
/*
* $Header: /home/projects/jaxen/scm/jaxen/src/java/test/org/jaxen/XPathTestBase.java,v 1.32 2005/06/15 23:52:40 bewins Exp $
* $Revision: 1.32 $
* $Date: 2005/06/15 23:52:40 $
*
* ====================================================================
*
* Copyright (C) 2000-2002 bob mcwhirter &amp; James Strachan.
* 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 disclaimer that follows
* these conditions in the documentation and/or other materials
* provided with the distribution.
*
* 3. The name "Jaxen" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact license@jaxen.org.
*
* 4. Products derived from this software may not be called "Jaxen", nor
* may "Jaxen" appear in their name, without prior written permission
* from the Jaxen Project Management (pm@jaxen.org).
*
* In addition, we request (but do not require) that you include in the
* end-user documentation provided with the redistribution and/or in the
* software itself an acknowledgement equivalent to the following:
* "This product includes software developed by the
* Jaxen Project (http://www.jaxen.org/)."
* Alternatively, the acknowledgment may be graphical using the logos
* available at http://www.jaxen.org/
*
* 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 Jaxen AUTHORS OR THE PROJECT
* 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 Jaxen Project and was originally
* created by bob mcwhirter &lt;bob@werken.com> and
* James Strachan &lt;jstrachan@apache.org>. For more information on the
* Jaxen Project, please see &lt;http://www.jaxen.org/>.
*
* $Id: XPathTestBase.java,v 1.32 2005/06/15 23:52:40 bewins Exp $
*/
package org.jaxen;
import junit.framework.TestCase;
import org.jaxen.function.StringFunction;
import org.jaxen.saxpath.helpers.XPathReaderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public abstract class XPathTestBase extends TestCase
{
protected static String VAR_URI = "http://jaxen.org/test-harness/var";
protected static String TESTS_XML = "xml/test/tests.xml";
protected static boolean verbose = true;
protected static boolean debug = true;
private ContextSupport contextSupport;
public XPathTestBase(String name)
{
super( name );
}
public void setUp() throws ParserConfigurationException
{
this.contextSupport = null;
System.setProperty( XPathReaderFactory.DRIVER_PROPERTY,
"" );
log( "-----------------------------" );
}
public void log(String text)
{
log( verbose,
text );
}
public void log(boolean actualVerbose,
String text)
{
if ( ! actualVerbose )
{
return;
}
System.out.println( text );
}
protected void assertCountXPath(int expectedSize, Object context, String xpathStr) throws JaxenException {
try
{
assertCountXPath2(expectedSize, context, xpathStr);
}
catch (UnsupportedAxisException e)
{
log ( debug,
" ## SKIPPED -- Unsupported Axis" );
}
}
protected Object assertCountXPath2(int expectedSize, Object context, String xpathStr) throws JaxenException {
log ( debug,
" Select :: " + xpathStr );
BaseXPath xpath = new BaseXPath( xpathStr );
List results = xpath.selectNodes( getContext( context ) );
log ( debug,
" Expected Size :: " + expectedSize );
log ( debug,
" Result Size :: " + results.size() );
if ( expectedSize != results.size() )
{
log ( debug,
" ## FAILED" );
log ( debug,
" ## xpath: " + xpath + " = " + xpath.debug() );
Iterator resultIter = results.iterator();
while ( resultIter.hasNext() )
{
log ( debug,
" --> " + resultIter.next() );
}
}
assertEquals( xpathStr,
expectedSize,
results.size() );
if (expectedSize > 0) {
return results.get(0);
}
return null;
}
protected void assertInvalidXPath(Object context, String xpathStr) throws JaxenException {
try
{
log ( debug,
" Select :: " + xpathStr );
BaseXPath xpath = new BaseXPath( xpathStr );
List results = xpath.selectNodes( getContext( context ) );
log ( debug,
" Result Size :: " + results.size() );
fail("An exception was expected.");
}
catch (UnsupportedAxisException e)
{
log ( debug,
" ## SKIPPED -- Unsupported Axis" );
}
catch (JaxenException e) {
log (debug, " Caught expected exception "+e.getMessage());
}
}
protected void assertValueOfXPath(String expected, Object context, String xpathStr) throws JaxenException {
try
{
BaseXPath xpath = new BaseXPath( xpathStr );
Object node = xpath.evaluate( getContext( context ) );
String result = StringFunction.evaluate( node,
getNavigator() );
log ( debug,
" Select :: " + xpathStr );
log ( debug,
" Expected :: " + expected );
log ( debug,
" Result :: " + result );
if ( ! expected.equals( result ) )
{
log ( debug,
" ## FAILED" );
log ( debug,
" ## xpath: " + xpath + " = " + xpath.debug() );
}
assertEquals( xpathStr,
expected,
result );
}
catch (UnsupportedAxisException e)
{
log ( debug,
" ## SKIPPED -- Unsupported Axis " );
}
}
protected Context getContext(Object contextNode)
{
Context context = new Context( getContextSupport() );
List list = new ArrayList( 1 );
list.add( contextNode );
context.setNodeSet( list );
return context;
}
public ContextSupport getContextSupport()
{
if ( this.contextSupport == null )
{
this.contextSupport = new ContextSupport( new SimpleNamespaceContext(),
XPathFunctionContext.getInstance(),
new SimpleVariableContext(),
getNavigator() );
}
return this.contextSupport;
}
public abstract Navigator getNavigator();
public abstract Object getDocument(String url) throws Exception;
public void testGetNodeType() throws FunctionCallException, UnsupportedAxisException
{
Navigator nav = getNavigator();
Object document = nav.getDocument("xml/testNamespaces.xml");
int count = 0;
Iterator descendantOrSelfAxisIterator = nav.getDescendantOrSelfAxisIterator(document);
while (descendantOrSelfAxisIterator.hasNext()) {
Object node = descendantOrSelfAxisIterator.next();
Iterator namespaceAxisIterator = nav.getNamespaceAxisIterator(node);
while (namespaceAxisIterator.hasNext()) {
count++;
assertEquals("Node type mismatch", Pattern.NAMESPACE_NODE, nav.getNodeType(namespaceAxisIterator.next()));
}
}
assertEquals(25, count);
}
</text>
<apply-templates select="node()|@*"/>
<text>
}
</text>
</template>
<template match="context">
<text>
public void test</text><value-of select="generate-id()"/><text>() throws JaxenException {
Navigator nav = getNavigator();
String url = "</text><value-of select="../@url"/><text>";
log( "Document [" + url + "]" );
Object document = nav.getDocument(url);
XPath contextpath = new BaseXPath("</text><value-of select="@select"/><text>", nav);
log( "Initial Context :: " + contextpath );
List list = contextpath.selectNodes(document);
</text>
<if test="count(namespace::*) > count(../namespace::*)">
<text>
SimpleNamespaceContext nsContext = new SimpleNamespaceContext();</text>
<for-each select="namespace::*[local-name() != 'var' and local-name() != 'xml']">
<text>
nsContext.addNamespace( "</text><value-of select="local-name()"/><text>", "</text><value-of select="."/><text>" );</text>
</for-each>
<text>
getContextSupport().setNamespaceContext( nsContext );</text>
</if>
<if test="@*[namespace-uri() = 'http://jaxen.org/test-harness/var']">
<text>
SimpleVariableContext varContext = new SimpleVariableContext();</text>
<for-each select="@*[namespace-uri() = 'http://jaxen.org/test-harness/var']">
<text>
varContext.setVariableValue(null, "</text><value-of select="local-name()"/><text>", "</text><value-of select="."/><text>" );</text>
</for-each>
<text>
getContextSupport().setVariableContext( varContext );</text>
</if>
<text>
Iterator iter = list.iterator();
while (iter.hasNext()) {
Object context = iter.next();</text>
<apply-templates select="node()|@*"/>
<text>
}
}</text>
</template>
<template match="test[@exception]">
<text>
assertInvalidXPath(context, "</text><value-of select='@select'/><text>");</text>
</template>
<template match="test[valueOf]">
<choose>
<when test="@count">
<text>
try
{
Object result = assertCountXPath2(</text><value-of select="@count"/><text>, context, "</text><value-of select="@select"/><text>");</text>
<for-each select="valueOf">
<text>
assertValueOfXPath("</text><value-of select="."/><text>", result, "</text><value-of select="@select"/><text>");</text>
</for-each>
<text>
}
catch (UnsupportedAxisException e)
{
log ( debug, " ## SKIPPED -- Unsupported Axis" );
}</text>
</when>
<otherwise>
<text>
try
{
BaseXPath xpath = new BaseXPath( "</text><value-of select="@select"/><text>" );
List results = xpath.selectNodes( getContext( context ) );
Object result = results.get(0);</text>
<for-each select="valueOf">
<text>
assertValueOfXPath("</text><value-of select="."/><text>", result, "</text><value-of select="@select"/><text>");</text>
</for-each>
<text>
}
catch (UnsupportedAxisException e)
{
log ( debug, " ## SKIPPED -- Unsupported Axis" );
}</text>
</otherwise>
</choose>
</template>
<template match="test">
<text>
assertCountXPath(</text><value-of select="@count"/><text>, context, "</text><value-of select="@select"/><text>");</text>
</template>
<template match="valueOf">
<text>
assertValueOfXPath("</text><value-of select="."/>", context, "<value-of select="@select"/><text>");</text>
</template>
<template match="comment()"><text>
/*</text><value-of select="."/><text>
*/</text>
</template>
<template match="node()|@*"><apply-templates select="node()|@*"/></template>
</stylesheet>

View file

@ -0,0 +1,22 @@
<Template>
<Application1 xmlns:xplt="http://www.xxxx.com/"
xmlns:xpl="http://www.xxxx.com/"
version="3.0"
randomAttribute="foo"
>
<xpl:insertText/>
<xplt:anyElement>
<Name/>
</xplt:anyElement>
</Application1>
<Application2 xmlns:xplt="http://www.xxxx.com/"
xmlns:xpl="http://www.xxxx.com/"
version="3.0"
>
<xpl:insertText/>
<xplt:anyElement>
<Name/>
</xplt:anyElement>
</Application2>
</Template>

View file

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN"
"http://my.netscape.com/publish/formats/rss-0.91.dtd">
<rss version="0.91">
<channel>
<title>xmlhack</title>
<link>http://www.xmlhack.com</link>
<description>Developer news from the XML community</description>
<language>en-us</language>
<copyright>Copyright 1999-2001, xmlhack team.</copyright>
<managingEditor>editor@xmlhack.com</managingEditor>
<webMaster>webmaster@xmlhack.com</webMaster>
<image>
<title>xmlhack</title>
<url>http://www.xmlhack.com/images/mynetscape88.gif</url>
<link>http://www.xmlhack.com</link>
<width>88</width>
<height>31</height>
<description>News, opinions, tips and issues concerning XML development</description>
</image>
<item x='0'>
<title>Experimental non-XML syntax for RELAX NG</title>
<link>http://www.xmlhack.com/read.php?item=1343</link>
<description>
James Clark has announced the release of an experimental non-XML syntax for RELAX
NG and a Java translator implementation that converts
instances of the syntax into RELAX NG's XML syntax.
</description>
<category>Schemas</category>
</item>
<item x='1'>
<title>Long-awaited entity-resolver Java classes finally released</title>
<link>http://www.xmlhack.com/read.php?item=1342</link>
<description>Norman Walsh has
announced the release of SAX entityResolver() and JAXP
URIResolver() Java
classes he wrote to implement the OASIS XML Catalogs
Committee Specification (in addition to the TR9401 and
Apache XCatalogs specifications).
</description>
<category>SGML/XML</category>
<category>Java</category>
</item>
<item x='3'>
<title>Beepcore-C framework released</title>
<link>http://www.xmlhack.com/read.php?item=1341</link>
<description>Invisible Worlds have announced the publication of Beepcore-C, an implementation of the BEEP framework written in C.</description>
<category>Protocols</category>
<category>C++</category>
</item>
<item>
<title>SVG and XSL-FO by example</title>
<link>http://www.xmlhack.com/read.php?item=1340</link>
<description>Jirka Jirat has announced the
addition of an XSL-FO and SVG examples repository to the Zvon developer
reference site.</description>
<category>SVG</category>
<category>XSL-FO</category>
</item>
</channel>
</rss>

10
test/rexml/data/text.xml Normal file
View file

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<foo>
<bar>
baz
<cheese id="3"/>
baz
<cheese/>
baz
</bar>
</foo>

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,590 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Rev 1.05
Changed the <gram> element name to <pos>
Added the g_gend attribute
moved the s_inf element
-->
<!-- Rev 1.04
Changes:
Rename the project "JMdict" and add the g_lang attribute to the
<gloss> entity - 08 May 1999
Moved the <gram>, <field> and <misc> elements down to be in the
<sense> region, as suggested by Chris Czeyka. I have also tidied up
some of the "*" as he suggested. - 27 May 2000
Added the re_nokanji element - Sep 2003.
-->
<!DOCTYPE JMdict [
<!ELEMENT JMdict (entry*)>
<!-- -->
<!ELEMENT entry (ent_seq, k_ele*, r_ele+, info*, sense+)>
<!-- Entries consist of kanji elements, reading elements,
general information and sense elements. Each entry must have at
least one reading element and one sense element. Others are optional.
-->
<!ELEMENT ent_seq (#PCDATA)>
<!-- A unique numeric sequence number for each entry
-->
<!ELEMENT k_ele (keb, ke_inf*, ke_pri*)>
<!-- The kanji element, or in its absence, the reading element, is
the defining component of each entry.
The overwhelming majority of entries will have a single kanji
element associated with a word in Japanese. Where there are
multiple kanji elements within an entry, they will be orthographical
variants of the same word, either using variations in okurigana, or
alternative and equivalent kanji. Common "mis-spellings" may be
included, provided they are associated with appropriate information
fields. Synonyms are not included; they may be indicated in the
cross-reference field associated with the sense element.
-->
<!ELEMENT keb (#PCDATA)>
<!-- This element will contain a word or short phrase in Japanese
which is written using at least one kanji. The valid characters are
kanji, kana, related characters such as chouon and kurikaeshi, and
in exceptional cases, letters from other alphabets.
-->
<!ELEMENT ke_inf (#PCDATA)>
<!-- This is a coded information field related specifically to the
orthography of the keb, and will typically indicate some unusual
aspect, such as okurigana irregularity.
-->
<!ELEMENT ke_pri (#PCDATA)>
<!-- This and the equivalent re_pri field are provided to record
information about the relative priority of the entry, and consist
of codes indicating the word appears in various references which
can be taken as an indication of the frequency with which the word
is used. This field is intended for use either by applications which
want to concentrate on entries of a particular priority, or to
generate subset files.
The current values in this field are:
- news1/2: appears in the "wordfreq" file compiled by Alexandre Girardi
from the Mainichi Shimbun. (See the Monash ftp archive for a copy.)
Words in the first 12,000 in that file are marked "news1" and words
in the second 12,000 are marked "news2".
- ichi1/2: appears in the "Ichimango goi bunruishuu", Senmon Kyouiku
Publishing, Tokyo, 1998.
- spec1 and spec2: a small number of words use this marker when they
are detected as being common, but are not included in other lists.
- gai1: common loanwords, based on the wordfreq file.
- nfxx: this is an indicator of frequency-of-use ranking in the
wordfreq file. "xx" is the number of the set of 500 words in which
the entry can be found, with "01" assigned to the first 500, "02"
to the second, and so on.
The reason both the kanji and reading elements are tagged is because
on occasions a priority is only associated with a particular
kanji/reading pair.
-->
<!-- -->
<!ELEMENT r_ele (reb, re_nokanji?, re_restr*, re_inf*, re_pri*)>
<!-- The reading element typically contains the valid readings
of the word(s) in the kanji element using modern kanadzukai.
Where there are multiple reading elements, they will typically be
alternative readings of the kanji element. In the absence of a
kanji element, i.e. in the case of a word or phrase written
entirely in kana, these elements will define the entry.
-->
<!ELEMENT reb (#PCDATA)>
<!-- this element content is restricted to kana and related
characters such as chouon and kurikaeshi. Kana usage will be
consistent between the keb and reb elements; e.g. if the keb
contains katakana, so too will the reb.
-->
<!ELEMENT re_nokanji (#PCDATA)>
<!-- This element, which will usually have a null value, indicates
that the reb, while associated with the keb, cannot be regarded
as a true reading of the kanji. It is typically used for words
such as foreign place names, gairaigo which can be in kanji or
katakana, etc.
-->
<!ELEMENT re_restr (#PCDATA)>
<!-- This element is used to indicate when the reading only applies
to a subset of the keb elements in the entry. In its absence, all
readings apply to all kanji elements. The contents of this element
must exactly match those of one of the keb elements.
-->
<!ELEMENT re_inf (#PCDATA)>
<!-- General coded information pertaining to the specific reading.
Typically it will be used to indicate some unusual aspect of
the reading. -->
<!ELEMENT re_pri (#PCDATA)>
<!-- See the comment on ke_pri above. -->
<!-- -->
<!ELEMENT info (lang*, dial*, links*, bibl*, etym*, audit*)>
<!-- general coded information relating to the entry as a whole.-->
<!ELEMENT lang (#PCDATA)>
<!-- For loan-words, the ISO 639 two-letter code for the originating
language. -->
<!ELEMENT dial (#PCDATA)>
<!-- For words specifically associated with regional dialects in
Japanese, the entity code for that dialect, e.g. ksb for Kansaiben.
-->
<!ELEMENT bibl (bib_tag?, bib_txt?)>
<!ELEMENT bib_tag (#PCDATA)>
<!ELEMENT bib_txt (#PCDATA)>
<!-- Bibliographic information about the entry. The bib_tag will a
coded reference to an entry in an external bibliographic database.
The bib_txt field may be used for brief (local) descriptions.-->
<!ELEMENT etym (#PCDATA)>
<!-- This field is used to hold information about the etymology
of the entry. -->
<!ELEMENT links (link_tag, link_desc, link_uri)>
<!ELEMENT link_tag (#PCDATA)>
<!ELEMENT link_desc (#PCDATA)>
<!ELEMENT link_uri (#PCDATA)>
<!-- This element holds details of linking information to
entries in other electronic repositories. The link_tag will be
coded to indicate the type of link (text, image, sound), the
link_desc will provided a textual label for the link, and the
link_uri contains the actual URI. -->
<!ELEMENT audit (upd_date, upd_detl)>
<!ELEMENT upd_date (#PCDATA)>
<!ELEMENT upd_detl (#PCDATA)>
<!-- The audit element will contain the date and other information
about updates to the entry. Can be used to record the source of
the material. -->
<!-- -->
<!ELEMENT sense (stagk*, stagr*, pos*, xref*, ant*, field*, misc*, s_inf*, gloss*, example*)>
<!-- The sense element will record the translational equivalent
of the Japanese word, plus other related information. Where there
are several distinctly different meanings of the word, multiple
sense elements will be employed.
-->
<!ELEMENT stagk (#PCDATA)>
<!ELEMENT stagr (#PCDATA)>
<!-- These elements, if present, indicate that the sense is restricted
to the lexeme represented by the keb and/or reb. -->
<!ELEMENT xref (#PCDATA)*>
<!-- This element is used to indicate a cross-reference to another
entry with a similar or related meaning or sense. The content of
this element must exactly match that of a keb or reb element in
another entry.
-->
<!ELEMENT ant (#PCDATA)*>
<!-- This element is used to indicate another entry which is an
antonym of the current entry/sense. The content of this element
must exactly match that of a keb or reb element in another entry.
-->
<!ELEMENT pos (#PCDATA)>
<!-- Part-of-speech information about the entry/sense. Should use
appropriate entity codes.
-->
<!ELEMENT field (#PCDATA)>
<!-- Information about the field of application of the entry. When
absent, general application is implied. Entity coding for specific
fields of application. -->
<!ELEMENT misc (#PCDATA)>
<!-- This element is used for other relevant information about
the entry. -->
<!ELEMENT gloss (#PCDATA | pri)*>
<!-- Within each sense will be one or more "glosses", i.e.
target-language words or phrases which are equivalents to the
Japanese word. This element would normally be present, however it
may be omitted in entries which are purely for a cross-reference.
-->
<!ATTLIST gloss g_lang CDATA "en">
<!-- The g_lang attribute defines the target language of the
gloss. It will be coded using the two-letter language code from
the ISO 639 standard. When absent, the value "en" (i.e. English)
is the default value. -->
<!ATTLIST gloss g_gend CDATA #IMPLIED>
<!-- The g_gend attribute defines the gender of the gloss (typically
a noun in the target language. When absent, the gender is either
not relevant or has yet to be provided.
-->
<!ELEMENT pri (#PCDATA)>
<!-- These elements highlight particular target-language words which
are strongly associated with the Japanese word. The purpose is to
establish a set of target-language words which can effectively be
used as head-words in a reverse target-language/Japanese relationship.
-->
<!ELEMENT example (#PCDATA)>
<!-- The example elements provide for pairs of short Japanese and
target-language phrases or sentences which exemplify the usage of the
Japanese head-word and the target-language gloss. Words in example
fields would typically not be indexed by a dictionary application.
-->
<!ELEMENT s_inf (#PCDATA)>
<!-- The sense-information elements provided for additional
information to be recorded about a sense. Typical usage would
be to indicate such things as level of currency of a sense, the
regional variations, etc.
-->
<!-- The following entity codes are used for common elements within the
various information fields.
-->
<!ENTITY MA "martial arts term">
<!ENTITY X "rude or X-rated term (not displayed in educational software)">
<!ENTITY abbr "abbreviation">
<!ENTITY adj "adjective (keiyoushi)">
<!ENTITY adj-na "adjectival nouns or quasi-adjectives (keiyodoshi)">
<!ENTITY adj-no "nouns which may take the genitive case particle `no'">
<!ENTITY adj-pn "pre-noun adjectival (rentaishi)">
<!ENTITY adj-t "`taru' adjective">
<!ENTITY adv "adverb (fukushi)">
<!ENTITY adv-n "adverbial noun">
<!ENTITY adv-to "adverb taking the `to' particle">
<!ENTITY arch "archaism">
<!ENTITY ateji "ateji (phonetic) reading">
<!ENTITY aux "auxiliary">
<!ENTITY aux-v "auxiliary verb">
<!ENTITY aux-adj "auxiliary adjective">
<!ENTITY Buddh "Buddhist term">
<!ENTITY chn "children's language">
<!ENTITY col "colloquialism ">
<!ENTITY comp "computer terminology">
<!ENTITY conj "conjunction">
<!ENTITY derog "derogatory">
<!ENTITY ek "exclusively kanji">
<!ENTITY exp "Expressions (phrases, clauses, etc.)">
<!ENTITY fam "familiar language ">
<!ENTITY fem "female term or language">
<!ENTITY food "food term">
<!ENTITY geom "geometry term">
<!ENTITY gikun "gikun (meaning) reading">
<!ENTITY gram "grammatical term">
<!ENTITY hon "honorific or respectful (sonkeigo) language ">
<!ENTITY hum "humble (kenjougo) language ">
<!ENTITY iK "word containing irregular kanji usage">
<!ENTITY id "idiomatic expression ">
<!ENTITY ik "word containing irregular kana usage">
<!ENTITY int "interjection (kandoushi)">
<!ENTITY io "irregular okurigana usage">
<!ENTITY iv "irregular verb">
<!ENTITY ling "linguistics terminology">
<!ENTITY m-sl "manga slang">
<!ENTITY male "male term or language">
<!ENTITY male-sl "male slang">
<!ENTITY math "mathematics">
<!ENTITY mil "military">
<!ENTITY n "noun (common) (futsuumeishi)">
<!ENTITY n-adv "adverbial noun (fukushitekimeishi)">
<!ENTITY n-suf "noun, used as a suffix">
<!ENTITY n-pref "noun, used as a prefix">
<!ENTITY n-t "noun (temporal) (jisoumeishi)">
<!ENTITY neg "negative (in a negative sentence, or with negative verb)">
<!ENTITY neg-v "negative verb (when used with)">
<!ENTITY num "numeric">
<!ENTITY oK "word containing out-dated kanji ">
<!ENTITY obs "obsolete term">
<!ENTITY obsc "obscure term">
<!ENTITY ok "out-dated or obsolete kana usage">
<!ENTITY pol "polite (teineigo) language ">
<!ENTITY pref "prefix ">
<!ENTITY prt "particle ">
<!ENTITY physics "physics terminology">
<!ENTITY qv "quod vide (see another entry)">
<!ENTITY rare "rare">
<!ENTITY sl "slang">
<!ENTITY suf "suffix ">
<!ENTITY uK "word usually written using kanji alone ">
<!ENTITY uk "word usually written using kana alone ">
<!ENTITY v1 "Ichidan verb">
<!ENTITY v5 "Godan verb (not completely classified)">
<!ENTITY v5aru "Godan verb - -aru special class">
<!ENTITY v5b "Godan verb with `bu' ending">
<!ENTITY v5g "Godan verb with `gu' ending">
<!ENTITY v5k "Godan verb with `ku' ending">
<!ENTITY v5k-s "Godan verb - Iku/Yuku special class">
<!ENTITY v5m "Godan verb with `mu' ending">
<!ENTITY v5n "Godan verb with `nu' ending">
<!ENTITY v5r "Godan verb with `ru' ending">
<!ENTITY v5r-i "Godan verb with `ru' ending (irregular verb)">
<!ENTITY v5s "Godan verb with `su' ending">
<!ENTITY v5t "Godan verb with `tsu' ending">
<!ENTITY v5u "Godan verb with `u' ending">
<!ENTITY v5u-s "Godan verb with `u' ending (special class)">
<!ENTITY v5uru "Godan verb - Uru old class verb (old form of Eru)">
<!ENTITY vi "intransitive verb ">
<!ENTITY vk "Kuru verb - special class">
<!ENTITY vs "noun or participle which takes the aux. verb suru">
<!ENTITY vs-s "suru verb - special class">
<!ENTITY vs-i "suru verb - irregular">
<!ENTITY vz "zuru verb - (alternative form of -jiru verbs)">
<!ENTITY vt "transitive verb">
<!ENTITY vulg "vulgar expression or word ">
<!ENTITY mg "masculine gender">
<!ENTITY fg "feminine gender">
<!ENTITY ng "neuter gender">
]>
<!-- JMdict created: 2006-09-11 -->
<JMdict>
<!-- JMdict Japanese-Multilingual Dictionary file (XML format) -->
<!-- Using V1.05 of the DTD -->
<!-- Copyright J.W. Breen (jwb@csse.monash.edu.au) -->
<entry>
<ent_seq>1000000</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<r_ele>
<reb>くりかえし</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>repetition mark in katakana</gloss>
<gloss g_lang="de">Wiederholungszeichen für Katakana</gloss>
<gloss g_lang="de">normalerweise nur in vertikaler Schreibweise verwendet</gloss>
<gloss g_lang="fr">marque de la répétition dans katakana</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000010</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<r_ele>
<reb>くりかえし</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>voiced repetition mark in katakana</gloss>
<gloss g_lang="de">stimmhaftes Wiederholungszeichen für Katakana</gloss>
<gloss g_lang="de">normalerweise nur in vertikaler Schreibweise verwendet</gloss>
<gloss g_lang="fr">marque de la répétition sonore dans katakana</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000020</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<r_ele>
<reb>くりかえし</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>repetition mark in hiragana</gloss>
<gloss g_lang="de">Wiederholungszeichen für Hiragana</gloss>
<gloss g_lang="de">normalerweise nur in vertikaler Schreibweise verwendet</gloss>
<gloss g_lang="fr">marque de la répétition dans hiragana</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000030</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<r_ele>
<reb>くりかえし</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>voiced repetition mark in hiragana</gloss>
<gloss g_lang="de">stimmhaftes Wiederholungszeichen für Hiragana</gloss>
<gloss g_lang="de">normalerweise nur in vertikaler Schreibweise verwendet</gloss>
<gloss g_lang="fr">marque de la répétition sonore dans hiragana</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000040</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<r_ele>
<reb>おなじく</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>ditto mark</gloss>
<gloss g_lang="ru">знак "то же самое"</gloss>
<gloss g_lang="de">Wiederholungszeichen in Tabellen</gloss>
<gloss g_lang="fr">idem marque</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000050</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<r_ele>
<reb>どうじょう</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>"as above" mark</gloss>
<gloss g_lang="de">Abkürzung für "siehe oben"</gloss>
<gloss g_lang="fr">comme au-dessus</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000060</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<r_ele>
<reb>くりかえし</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>repetition of kanji (sometimes voiced)</gloss>
<gloss g_lang="de">Wiederholungszeichen für Kanji</gloss>
<gloss g_lang="de">(Laut wird durch Wiederholung manchmal stimmhaft)</gloss>
<gloss g_lang="fr">répétition de kanji(quelquefois a exprimé)</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000070</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<r_ele>
<reb>しめ</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>end or closure mark</gloss>
<gloss g_lang="de">Zeichen als eine Art Versiegelung über der zugeklebten Lasche auf der Rückseite eines Briefumschlages</gloss>
<gloss g_lang="fr">fin ou marque de la fermeture</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000080</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<k_ele>
<keb></keb>
<ke_inf>&iK;</ke_inf>
</k_ele>
<r_ele>
<reb>かんすうじゼロ</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<xref>漢数字</xref>
<xref>ゼロ</xref>
<gloss>"kanji" zero</gloss>
<gloss g_lang="de">Kanji-Ziffer für Null</gloss>
<gloss g_lang="fr">kanji</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000090</ent_seq>
<k_ele>
<keb></keb>
</k_ele>
<k_ele>
<keb></keb>
<ke_inf>&iK;</ke_inf>
</k_ele>
<r_ele>
<reb>まる</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>circle (sometimes used for zero)</gloss>
<gloss g_lang="ru">круг</gloss>
<gloss g_lang="ru">но́ль</gloss>
<gloss g_lang="de">Kreis</gloss>
<gloss g_lang="de">Markierung für "richtig"</gloss>
<gloss g_lang="de">Maru</gloss>
<gloss g_lang="de">(ein japan. Schriftfont hat mindestens drei verschiedene Codierungen und Darstellungen für "maru")</gloss>
<gloss g_lang="fr">entourez</gloss>
<gloss g_lang="fr">mettez à zéro</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000100</ent_seq>
<k_ele>
<keb>ABC順</keb>
</k_ele>
<r_ele>
<reb>エービーシーじゅん</reb>
</r_ele>
<r_ele>
<reb>ええびいしいじゅん</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>alphabetical order</gloss>
<gloss g_lang="de">alphabetische Ordnung</gloss>
<gloss g_lang="de">alphabetische Reihenfolge</gloss>
<gloss g_lang="fr">ordre alphabétique</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000110</ent_seq>
<k_ele>
<keb>CDプレーヤー</keb>
</k_ele>
<r_ele>
<reb>シーディープレーヤー</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>CD player</gloss>
<gloss g_lang="ru">CD плеер</gloss>
<gloss g_lang="ru">проигрыватель компакт-дисков</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000120</ent_seq>
<k_ele>
<keb>Hな映画</keb>
</k_ele>
<k_ele>
<keb>エッチな映画</keb>
</k_ele>
<r_ele>
<reb>エッチなえいが</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>pornographic film</gloss>
<gloss>salacious film</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000130</ent_seq>
<k_ele>
<keb>N響</keb>
</k_ele>
<r_ele>
<reb>エヌきょう</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<misc>&abbr;</misc>
<gloss>NHK Symphony Orchestra</gloss>
<gloss g_lang="fr">NHK Symphonie Orchestre(abbr)</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000140</ent_seq>
<r_ele>
<reb>Oバック</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>O-back</gloss>
<gloss>skirt with peek-a-boo hole in rump</gloss>
<gloss g_lang="fr">O En arrière</gloss>
<gloss g_lang="fr">contournez avec coucou trou dans croupe</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
<entry>
<ent_seq>1000150</ent_seq>
<r_ele>
<reb>RS232ケーブル</reb>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>rs232 cable</gloss>
<gloss g_lang="fr">les rs232 câblent</gloss>
<gloss g_lang="fr">(JF2)</gloss>
</sense>
</entry>
</JMdict>

View file

@ -0,0 +1,678 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css"
href="../../documentation/documentation.css"
?>
<?xml-stylesheet type="text/xsl"
href="../../documentation/documentation.xsl"
?>
<!DOCTYPE documentation SYSTEM "http://www.germane-software.com/software/documentation/documentation.dtd">
<documentation>
<head>
<title>REXML Tutorial</title>
<version>$Revision: 1.1.2.1 $</version>
<date>*2001-296+594</date>
<home>http://www.germane-software.com/~ser/software/rexml</home>
<base></base>
<language>ruby</language>
<author email="ser@germane-software.com"
href="http://www.germane-software.com/~ser">Sean Russell</author>
</head>
<overview>
<purpose lang="en">
<p>This is a tutorial for using <link
href="http://www.germane-software.com/~ser/software/rexml">REXML</link>,
a pure Ruby XML processor.</p>
</purpose>
<general>
<p>REXML was inspired by the Electric XML library for Java, which
features an easy-to-use API, small size, and speed. Hopefully, REXML,
designed with the same philosophy, has these same features. I've tried
to keep the API as intuitive as possible, and have followed the Ruby
methodology for method naming and code flow, rather than mirroring the
Java API.</p>
<p>REXML supports both tree and stream document parsing. Stream parsing
is faster (about 1.5 times as fast). However, with stream parsing, you
don't get access to features such as XPath.</p>
<p>The <link href="../doc/index.html">API</link> documentation also
contains code snippits to help you learn how to use various methods.
This tutorial serves as a starting point and quick guide to using
REXML.</p>
<subsection title="Tree Parsing XML and accessing Elements">
<p>We'll start with parsing an XML document</p>
<example>require "rexml/document"
file = File.new( "mydoc.xml" )
doc = REXML::Document.new file</example>
<p>Line 3 creates a new document and parses the supplied file. You can
also do the following</p>
<example>require "rexml/document"
include REXML # so that we don't have to prefix everything with REXML::...
string = &lt;&lt;EOF
&lt;mydoc&gt;
&lt;someelement attribute="nanoo"&gt;Text, text, text&lt;/someelement&gt;
&lt;/mydoc&gt;
EOF
doc = Document.new string</example>
<p>So parsing a string is just as easy as parsing a file. For future
examples, I'm going to omit both the <code>require</code> and
<code>include</code> lines.</p>
<p>Once you have a document, you can access elements in that document
in a number of ways:</p>
<list>
<item>The <code>Element</code> class itself has
<code>each_element_with_attribute</code>, a common way of accessing
elements.</item>
<item>The attribute <code>Element.elements</code> is an
<code>Elements</code> class instance which has the <code>each</code>
and <code>[]</code> methods for accessing elements. Both methods can
be supplied with an XPath for filtering, which makes them very
powerful.</item>
<item>Since <code>Element</code> is a subclass of Parent, you can
also access the element's children directly through the Array-like
methods <code>Element[], Element.each, Element.find,
Element.delete</code>. This is the fastest way of accessing
children, but note that, being a true array, XPath searches are not
supported, and that all of the element children are contained in
this array, not just the Element children.</item>
</list>
<p>Here are a few examples using these methods. First is the source
document used in the examples. Save this as mydoc.xml before running
any of the examples that require it:</p>
<example title="The source document">&lt;inventory title="OmniCorp Store #45x10^3"&gt;
&lt;section name="health"&gt;
&lt;item upc="123456789" stock="12"&gt;
&lt;name&gt;Invisibility Cream&lt;/name&gt;
&lt;price&gt;14.50&lt;/price&gt;
&lt;description&gt;Makes you invisible&lt;/description&gt;
&lt;/item&gt;
&lt;item upc="445322344" stock="18"&gt;
&lt;name&gt;Levitation Salve&lt;/name&gt;
&lt;price&gt;23.99&lt;/price&gt;
&lt;description&gt;Levitate yourself for up to 3 hours per application&lt;/description&gt;
&lt;/item&gt;
&lt;/section&gt;
&lt;section name="food"&gt;
&lt;item upc="485672034" stock="653"&gt;
&lt;name&gt;Blork and Freen Instameal&lt;/name&gt;
&lt;price&gt;4.95&lt;/price&gt;
&lt;description&gt;A tasty meal in a tablet; just add water&lt;/description&gt;
&lt;/item&gt;
&lt;item upc="132957764" stock="44"&gt;
&lt;name&gt;Grob winglets&lt;/name&gt;
&lt;price&gt;3.56&lt;/price&gt;
&lt;description&gt;Tender winglets of Grob. Just add water&lt;/description&gt;
&lt;/item&gt;
&lt;/section&gt;
&lt;/inventory&gt;</example>
<example title="Accessing Elements">doc = Document.new File.new("mydoc.xml")
doc.elements.each("inventory/section") { |element| puts element.attributes["name"] }
# -&gt; health
# -&gt; food
doc.elements.each("*/section/item") { |element| puts element.attributes["upc"] }
# -&gt; 123456789
# -&gt; 445322344
# -&gt; 485672034
# -&gt; 132957764
root = doc.root
puts root.attributes["title"]
# -&gt; OmniCorp Store #45x10^3
puts root.elements["section/item[@stock='44']"].attributes["upc"]
# -&gt; 132957764
puts root.elements["section"].attributes["name"]
# -&gt; health (returns the first encountered matching element)
puts root.elements[1].attributes["name"]
# -&gt; health (returns the FIRST child element)
root.detect {|node| node.kind_of? Element and node.attributes["name"] == "food" }</example>
<p>Notice the second-to-last line of code. Element children in REXML
are indexed starting at 1, not 0. This is because XPath itself counts
elements from 1, and REXML maintains this relationship; IE,
<code>root.elements['*[1]'] == root.elements[1]</code>. The last line
finds the first child element with the name of "food". As you can see
in this example, accessing attributes is also straightforward.</p>
<p>You can also access xpaths directly via the XPath class.</p>
<example title="Using XPath"># The invisibility cream is the first &lt;item&gt;
invisibility = XPath.first( doc, "//item" )
# Prints out all of the prices
XPath.each( doc, "//price") { |element| puts element.text }
# Gets an array of all of the "name" elements in the document.
names = XPath.match( doc, "//name" ) </example>
<p>Another way of getting an array of matching nodes is through
Element.elements.to_a(). Although this is a method on elements, if
passed an XPath it can return an array of arbitrary objects. This is
due to the fact that XPath itself can return arbitrary nodes
(Attribute nodes, Text nodes, and Element nodes).</p>
<example title="Using to_a()">all_elements = doc.elements.to_a
all_children = doc.to_a
all_upc_strings = doc.elements.to_a( "//item/attribute::upc" )
all_name_elements = doc.elements.to_a( "//name" )</example>
</subsection>
<subsection title="Text Nodes">
<p>REXML attempts to make the common case simple, but this means that
the uncommon case can be complicated. This is especially true with
Text nodes.</p>
<p>Text nodes have a lot of behavior, and in the case of internal
entities, what you get may be different from what you expect. When
REXML reads an XML document, in parses the DTD and creates an internal
table of entities. If it finds any of these entities in the document,
it replaces them with their values:</p>
<example title="Entity Replacement">doc = Document.new '&lt;!DOCTYPE foo [
&lt;!ENTITY ent "replace"&gt;
]&gt;&lt;a&gt;&amp;ent;&lt;/a&gt;'
doc.root.text #-&gt; "replace"
</example>
<p>When you write the document back out, REXML replaces the values
with the entity reference:</p>
<example>doc.to_s
# Generates:
# &lt;!DOCTYPE foo [
# &lt;!ENTITY ent "replace"&gt;
# ]&gt;&lt;a&gt;&amp;ent;&lt;/a&gt;</example>
<p>But there's a problem. What happens if only some of the words are
also entity reference values?</p>
<example>doc = Document.new '&lt;!DOCTYPE foo [
&lt;!ENTITY ent "replace"&gt;
]&gt;&lt;a&gt;replace &amp;ent;&lt;/a&gt;'
doc.root.text #-&gt; "replace replace"
</example>
<p>Well, REXML does the only thing it can:</p>
<example>doc.to_s
# Generates:
# &lt;!DOCTYPE foo [
# &lt;!ENTITY ent "replace"&gt;
# ]&gt;&lt;a&gt;&amp;ent; &amp;ent;&lt;/a&gt;</example>
<p>This is probably not what you expect. However, when designing
REXML, I had a choice between this behavior, and using immutable text
nodes. The problem is that, if you can change the text in a node,
REXML can never tell which tokens you want to have replaced with
entities. There is a wrinkle: REXML will write what it gets in as long
as you don't access the text. This is because REXML does lazy
evaluation of entities. Therefore,</p>
<example title="Lazy Evaluation">doc = Document.new( '&lt;!DOCTYPE foo
[ &lt;!ENTITY ent "replace"&gt; ]&gt;&lt;a&gt;replace
&amp;ent;&lt;/a&gt;' ) doc.to_s # Generates: # &lt;!DOCTYPE foo [ #
&lt;!ENTITY ent "replace"&gt; # ]&gt;&lt;a&gt;<emphasis>replace
&amp;ent;</emphasis>&lt;/a&gt; doc.root.text #-&gt; Now accessed,
entities have been resolved doc.to_s # Generates: # &lt;!DOCTYPE foo [
# &lt;!ENTITY ent "replace"&gt; # ]&gt;&lt;a&gt;<emphasis>&amp;ent;
&amp;ent;</emphasis>&lt;/a&gt;</example>
<p>There is a programmatic solution: <code>:raw</code>. If you set the
<code>:raw</code> flag on any Text or Element node, the entities
within that node will not be processed. This means that you'll have to
deal with entities yourself:</p>
<example title="Entity Replacement">doc = Document.new('&lt;!DOCTYPE
foo [ &lt;!ENTITY ent "replace"&gt; ]&gt;&lt;a&gt;replace
&amp;ent;&lt;/a&gt;',<emphasis>{:raw=&gt;:all})</emphasis>
doc.root.text #-&gt; "replace &amp;ent;" doc.to_s # Generates: #
&lt;!DOCTYPE foo [ # &lt;!ENTITY ent "replace"&gt; #
]&gt;&lt;a&gt;replace &amp;ent;&lt;/a&gt;</example>
</subsection>
<subsection title="Creating XML documents">
<p>Again, there are a couple of mechanisms for creating XML documents
in REXML. Adding elements by hand is faster than the convenience
method, but which you use will probably be a matter of aesthetics.</p>
<example title="Creating elements">el = someelement.add_element "myel"
# creates an element named "myel", adds it to "someelement", and returns it
el2 = el.add_element "another", {"id"=&gt;"10"}
# does the same, but also sets attribute "id" of el2 to "10"
el3 = Element.new "blah"
el1.elements &lt;&lt; el3
el3.attributes["myid"] = "sean"
# creates el3 "blah", adds it to el1, then sets attribute "myid" to "sean"</example>
<p>If you want to add text to an element, you can do it by either
creating Text objects and adding them to the element, or by using the
convenience method <code>text=</code></p>
<example title="Adding text">el1 = Element.new "myelement"
el1.text = "Hello world!"
# -&gt; &lt;myelement&gt;Hello world!&lt;/myelement&gt;
el1.add_text "Hello dolly"
# -&gt; &lt;myelement&gt;Hello world!Hello dolly&lt;/element&gt;
el1.add Text.new("Goodbye")
# -&gt; &lt;myelement&gt;Hello world!Hello dollyGoodbye&lt;/element&gt;
el1 &lt;&lt; Text.new(" cruel world")
# -&gt; &lt;myelement&gt;Hello world!Hello dollyGoodbye cruel world&lt;/element&gt;</example>
<p>But note that each of these text objects are still stored as
separate objects; <code>el1.text</code> will return "Hello world!";
<code>el1[2]</code> will return a Text object with the contents
"Goodbye".</p>
<p>Please be aware that all text nodes in REXML are UTF-8 encoded, and
all of your code must reflect this. You may input and output other
encodings (UTF-8, UTF-16, ISO-8859-1, and UNILE are all supported,
input and output), but within your program, you must pass REXML UTF-8
strings.</p>
<p>I can't emphasize this enough, because people do have problems with
this. REXML can't possibly alway guess correctly how your text is
encoded, so it always assumes the text is UTF-8. It also does not warn
you when you try to add text which isn't properly encoded, for the
same reason. You must make sure that you are adding UTF-8 text.
&#160;If you're adding standard 7-bit ASCII, which is most common, you
don't have to worry. &#160;If you're using ISO-8859-1 text (characters
above 0x80), you must convert it to UTF-8 before adding it to an
element. &#160;You can do this with the shard:
<code>text.unpack("C*").pack("U*")</code>. If you ignore this warning
and add 8-bit ASCII characters to your documents, your code may
work... or it may not. &#160;In either case, REXML is not at fault.
You have been warned.</p>
<p>One last thing: alternate encoding output support only works from
Document.write() and Document.to_s(). If you want to write out other
nodes with a particular encoding, you must wrap your output object
with Output:</p>
<example title="Encoded Output">e = Element.new "&lt;a/&gt;"
e.text = "f\xfcr" # ISO-8859-1 'ü'
o = ''
e.write( Output.new( o, "ISO-8859-1" ) )
</example>
<p>You can pass Output any of the supported encodings.</p>
<p>If you want to insert an element between two elements, you can use
either the standard Ruby array notation, or
<code>Parent.insert_before</code> and
<code>Parent.insert_after</code>.</p>
<example title="Inserts">doc = Document.new "&lt;a&gt;&lt;one/&gt;&lt;three/&gt;&lt;/a&gt;"
doc.root[1,0] = Element.new "two"
# -&gt; &lt;a&gt;&lt;one/&gt;&lt;two/&gt;&lt;three/&gt;&lt;/a&gt;
three = doc.elements["a/three"]
doc.root.insert_after three, Element.new "four"
# -&gt; &lt;a&gt;&lt;one/&gt;&lt;two/&gt;&lt;three/&gt;&lt;four/&gt;&lt;/a&gt;
# A convenience method allows you to insert before/after an XPath:
doc.root.insert_after( "//one", Element.new("one-five") )
# -&gt; &lt;a&gt;&lt;one/&gt;&lt;one-five/&gt;&lt;two/&gt;&lt;three/&gt;&lt;four/&gt;&lt;/a&gt;
# Another convenience method allows you to insert after/before an element:
four = doc.elements["//four"]
four.previous_sibling = Element.new("three-five")
# -&gt; &lt;a&gt;&lt;one/&gt;&lt;one-five/&gt;&lt;two/&gt;&lt;three/&gt;&lt;three-five/&gt;&lt;four/&gt;&lt;/a&gt;</example>
<p>The <code>raw</code> flag in the <code>Text</code> constructor can
be used to tell REXML to leave strings which have entities defined for
them alone.</p>
<example title="Raw text">doc = Document.new( "&lt;?xml version='1.0?&gt;
&lt;!DOCTYPE foo SYSTEM 'foo.dtd' [
&lt;!ENTITY % s "Sean"&gt;
]&gt;
&lt;a/&gt;"
t = Text.new( "Sean", false, nil, false )
doc.root.text = t
t.to_s # -&gt; &amp;s;
t = Text.new( "Sean", false, nil, true )
doc.root.text = t
t.to_s # -&gt; Sean</example>
<p>Note that, in all cases, the <code>value()</code> method returns
the text with entities expanded, so the <code>raw</code> flag only
affects the <code>to_s()</code> method. If the <code>raw</code> is set
for a text node, then <code>to_s()</code> will not entities will not
normalize (turn into entities) entity values. You can not create raw
text nodes that contain illegal XML, so the following will generate a
parse error:</p>
<example>t = Text.new( "&amp;", false, nil, true )</example>
<p>You can also tell REXML to set the Text children of given elements
to raw automatically, on parsing or creating:</p>
<example title="Automatic raw text handling">doc = REXML::Document.new( source, { :raw =&gt; %w{ tag1 tag2 tag3 } }</example>
<p>In this example, all tags named "tag1", "tag2", or "tag3" will have
any Text children set to raw text. If you want to have all of the text
processed as raw text, pass in the :all tag:</p>
<example title="Raw documents">doc = REXML::Document.new( source, { :raw =&gt; :all })</example>
</subsection>
<subsection title="Writing a tree">
<p>There aren't many things that are more simple than writing a REXML
tree. Simply pass an object that supports <code>&lt;&lt;( String
)</code> to the <code>write</code> method of any object. In Ruby, both
IO instances (File) and String instances support &lt;&lt;.</p>
<example>doc.write $stdout
output = ""
doc.write output</example>
<p>If you want REXML to pretty-print output, pass <code>write()</code>
an indent value greater than -1:</p>
<example title="Write with pretty-printing">doc.write( $stdout, 0 )</example>
<p>REXML will not, by default, write out the XML declaration unless
you specifically ask for them. If a document is read that contains an
XML declaration, that declaration <emphasis>will</emphasis> be written
faithfully. The other way you can tell REXML to write the declaration
is to specifically add the declaration:</p>
<example title="Adding an XML Declaration to a Document">doc = Document.new
doc.add_element 'foo'
doc.to_s #-&gt; &lt;foo/&gt;
doc &lt;&lt; XMLDecl.new
doc.to_s #-&gt; &lt;?xml version='1.0'?&gt;&lt;foo/&gt;</example>
</subsection>
<subsection title="Iterating">
<p>There are four main methods of iterating over children.
<code>Element.each</code>, which iterates over all the children;
<code>Element.elements.each</code>, which iterates over just the child
Elements; <code>Element.next_element</code> and
<code>Element.previous_element</code>, which can be used to fetch the
next Element siblings; and <code>Element.next_sibling</code> and
<code>Eleemnt.previous_sibling</code>, which fetches the next and
previous siblings, regardless of type.</p>
</subsection>
<subsection title="Stream Parsing">
<p>REXML stream parsing requires you to supply a Listener class. When
REXML encounters events in a document (tag start, text, etc.) it
notifies your listener class of the event. You can supply any subset
of the methods, but make sure you implement method_missing if you
don't implement them all. A StreamListener module has been supplied as
a template for you to use.</p>
<example title="Stream parsing">list = MyListener.new
source = File.new "mydoc.xml"
REXML::Document.parse_stream(source, list)</example>
<p>Stream parsing in REXML is much like SAX, where events are
generated when the parser encounters them in the process of parsing
the document. When a tag is encountered, the stream listener's
<code>tag_start()</code> method is called. When the tag end is
encountered, <code>tag_end()</code> is called. When text is
encountered, <code>text()</code> is called, and so on, until the end
of the stream is reached. One other note: the method
<code>entity()</code> is called when an <code>&amp;entity;</code> is
encountered in text, and only then.</p>
<p>Please look at the <link
href="../doc/classes/REXML/StreamListener.html">StreamListener
API</link> for more information.<footnote>You must generate the API
documentation with rdoc or download the API documentation from the
REXML website for this documentation.</footnote></p>
</subsection>
<subsection title="Whitespace">
<p>By default, REXML respects whitespace in your document. In many
applications, you want the parser to compress whitespace in your
document. In these cases, you have to tell the parser which elements
you want to respect whitespace in by passing a context to the
parser:</p>
<example title="Compressing whitespace">doc = REXML::Document.new( source, { :compress_whitespace =&gt; %w{ tag1 tag2 tag3 } }</example>
<p>Whitespace for tags "tag1", "tag2", and "tag3" will be compressed;
all other tags will have their whitespace respected. Like :raw, you
can set :compress_whitespace to :all, and have all elements have their
whitespace compressed.</p>
<p>You may also use the tag <code>:respect_whitespace</code>, which
flip-flops the behavior. If you use <code>:respect_whitespace</code>
for one or more tags, only those elements will have their whitespace
respected; all other tags will have their whitespace compressed.</p>
</subsection>
<subsection title="Automatic Entity Processing">
<p>REXML does some automatic processing of entities for your
convenience. The processed entities are &amp;, &lt;, &gt;, ", and '.
If REXML finds any of these characters in Text or Attribute values, it
automatically turns them into entity references when it writes them
out. Additionally, when REXML finds any of these entity references in
a document source, it converts them to their character equivalents.
All other entity references are left unprocessed. If REXML finds an
&amp;, &lt;, or &gt; in the document source, it will generate a
parsing error.</p>
<example title="Entity processing">bad_source = "&lt;a&gt;Cats &amp; dogs&lt;/a&gt;"
good_source = "&lt;a&gt;Cats &amp;amp; &amp;#100;ogs&lt;/a&gt;"
doc = REXML::Document.new bad_source
# Generates a parse error
doc = REXML::Document.new good_source
puts doc.root.text
# -&gt; "Cats &amp; &amp;#100;ogs"
doc.root.write $stdout
# -&gt; "&lt;a&gt;Cats &amp;amp; &amp;#100;ogs&lt;/a&gt;"
doc.root.attributes["m"] = "x'y\"z"
puts doc.root.attributes["m"]
# -&gt; "x'y\"z"
doc.root.write $stdout
# -&gt; "&lt;a m='x&amp;apos;y&amp;quot;z'&gt;Cats &amp;amp; &amp;#100;ogs&lt;/a&gt;"</example>
</subsection>
<subsection title="Namespaces">
<p>Namespaces are fully supported in REXML and within the XPath
parser. There are a few caveats when using XPath, however:</p>
<list>
<item>If you don't supply a namespace mapping, the default namespace
mapping of the context element is used. This has its limitations,
but is convenient for most purposes.</item>
<item>If you need to supply a namespace mapping, you must use the
XPath methods <code>each</code>, <code>first</code>, and
<code>match</code> and pass them the mapping.</item>
</list>
<example title="Using namespaces">source = "&lt;a xmlns:x='foo' xmlns:y='bar'&gt;&lt;x:b id='1'/&gt;&lt;y:b id='2'/&gt;&lt;/a&gt;"
doc = Document.new source
doc.elements["/a/x:b"].attributes["id"] # -&gt; '1'
XPath.first(doc, "/a/m:b", {"m"=&gt;"bar"}).attributes["id"] # -&gt; '2'
doc.elements["//x:b"].prefix # -&gt; 'x'
doc.elements["//x:b"].namespace # -&gt; 'foo'
XPath.first(doc, "//m:b", {"m"=&gt;"bar"}).prefix # -&gt; 'y'</example>
</subsection>
<subsection title="Pull parsing">
<p>The pull parser API is not yet stable. When it settles down, I'll
fill in this section. For now, you'll have to bite the bullet and read
the <link
href="http://www.germane-software.com/software/rexml_doc/classes/REXML/PullParser.html">PullParser</link>
API docs. Ignore the PullListener class; it is a private helper
class.</p>
</subsection>
<subsection title="SAX2 Stream Parsing">
<p>The original REXML stream parsing API is very minimal. This also
means that it is fairly fast. For a more complex, more "standard" API,
REXML also includes a streaming parser with a SAX2+ API. This API
differs from SAX2 in a couple of ways, such as having more filters and
multiple notification mechanisms, but the core API is SAX2.</p>
<p>The two classes in the SAX2 API are <link
href="http://www.germane-software.com/software/rexml_doc/classes/REXML/SAX2Parser.html"><code>SAX2Parser</code></link>
and <link
href="http://www.germane-software.com/software/rexml_doc/classes/REXML/SAX2Listener.html"><code>SAX2Listener</code></link>.
You can use the parser in one of five ways, depending on your needs.
Three of the ways are useful if you are filtering for a small number
of events in the document, such as just printing out the names of all
of the elements in a document, or getting all of the text in a
document. The other two ways are for more complex processing, where
you want to be notified of multiple events. The first three involve
Procs, and the last two involve listeners. The listener mechanisms are
very similar to the original REXML streaming API, with the addition of
filtering options, and are faster than the proc mechanisms.</p>
<p>An example is worth a thousand words, so we'll just take a look at
a small example of each of the mechanisms. The first example involves
printing out only the text content of a document.</p>
<example title="Filtering for Events with Procs">require 'rexml/sax2parser'
parser = REXML::SAX2Parser.new( File.new( 'documentation.xml' ) )
parser.listen( :characters ) {|text| puts text }
parser.parse</example>
<p>In this example, we tell the parser to call our block for every
<code>characters</code> event. "characters" is what SAX2 calls Text
nodes. The event is identified by the symbol <code>:characters</code>.
There are a number of these events, including
<code>:element_start</code>, <code>:end_prefix_mapping</code>, and so
on; the events are named after the methods in the
<code>SAX2Listener</code> API, so refer to that document for a
complete list.</p>
<p>You can additionally filter for particular elements by passing an
array of tag names to the <code>listen</code> method. In further
examples, we will not include the <code>require</code> or parser
construction lines, as they are the same for all of these
examples.</p>
<example title="Filtering for Events on Particular Elements with Procs">parser.listen( :characters, %w{ changelog todo } ) {|text| puts text }
parser.parse</example>
<p>In this example, only the text content of changelog and todo
elements will be printed. The array of tag names can also contain
regular expressions which the element names will be matched
against.</p>
<p>Finally, as a shortcut, if you do not pass a symbol to the listen
method, it will default to <code>:element_start</code></p>
<example title="Default Events">parser.listen( %w{ item }) do |uri,localname,qname,attributes|
puts attributes['version']
end
parser.parse</example>
<p>This example prints the "version" attribute of all "item" elements
in the document. Notice that the number of arguments passed to the
block is larger than for <code>:text</code>; again, check the
SAX2Listener API for a list of what arguments are passed the blocks
for a given event.</p>
<p>The last two mechanisms for parsing use the SAX2Listener API. Like
StreamListener, SAX2Listener is a <code>module</code>, so you can
<code>include</code> it in your class to give you an adapter. To use
the listener model, create a class that implements some of the
SAX2Listener methods, or all of them if you don't include the
SAX2Listener model. Add them to a parser as you would blocks, and when
the parser is run, the methods will be called when events occur.
Listeners do not use event symbols, but they can filter on element
names.</p>
<example title="Filtering for Events with Listeners">listener1 = MySAX2Listener.new
listener2 = MySAX2Listener.new
parser.listen( listener1 )
parser.listen( %{ changelog, todo, credits }, listener2 )
parser.parse</example>
<p>In the previous example, <code>listener1</code> will be notified of
all events that occur, and <code>listener2</code> will only be
notified of events that occur in <code>changelog</code>,
<code>todo</code>, and <code>credits</code> elements. We also see that
multiple listeners can be added to the same parser; multiple blocks
can also be added, and listeners and blocks can be mixed together.</p>
<p>There is, as yet, no mechanism for recursion. Two upcoming features
of the SAX2 API will be the ability to filter based on an XPath, and
the ability to specify filtering on an elemnt and all of its
descendants.</p>
<p><em>WARNING:</em> The SAX2 API for dealing with doctype (DTD)
events almost <em>certainly</em> will change.</p>
</subsection>
<subsection title="Convenience methods">
<p>Michael Neumann contributed some convenience functions for nodes,
and they are general enough that I've included. Michael's use-case
examples follow: <example title="Node convenience functions">#
Starting with +root_node+, we recursively look for a node with the
given # +tag+, the given +attributes+ (a Hash) and whoose text equals
or matches the # +text+ string or regular expression. # # To find the
following node: # # &lt;td class='abc'&gt;text&lt;/td&gt; # # We use:
# # find_node(root, 'td', {'class' =&gt; 'abc'}, "text") # # Returns
+nil+ if no matching node was found. def find_node(root_node, tag,
attributes, text) root_node.find_first_recursive {|node| node.name ==
tag and attributes.all? {|attr, val| node.attributes[attr] == val} and
text === node.text } end # # Extract specific columns (specified by
the position of it's corrensponding # header column) from a table. # #
Given the following table: # # &lt;table&gt; # &lt;tr&gt; #
&lt;td&gt;A&lt;/td&gt; # &lt;td&gt;B&lt;/td&gt; #
&lt;td&gt;C&lt;/td&gt; # &lt;/tr&gt; # &lt;tr&gt; #
&lt;td&gt;A.1&lt;/td&gt; # &lt;td&gt;B.1&lt;/td&gt; #
&lt;td&gt;C.1&lt;/td&gt; # &lt;/tr&gt; # &lt;tr&gt; #
&lt;td&gt;A.2&lt;/td&gt; # &lt;td&gt;B.2&lt;/td&gt; #
&lt;td&gt;C.2&lt;/td&gt; # &lt;/tr&gt; # &lt;/table&gt; # # To extract
the first (A) and last (C) column: # # extract_from_table(root_node,
["A", "C"]) # # And you get this as result: # # [ # ["A.1", "C.1"], #
["A.2", "C.2"] # ] # def extract_from_table(root_node, headers) #
extract and collect all header nodes header_nodes = headers.collect {
|header| find_node(root_node, 'td', {}, header) } raise "some headers
not found" if header_nodes.compact.size &lt; headers.size # assert
that all headers have the same parent 'header_row', which is the row #
in which the header_nodes are contained. 'table' is the surrounding
table tag. header_row = header_nodes.first.parent table =
header_row.parent raise "different parents" unless header_nodes.all?
{|n| n.parent == header_row} # we now iterate over all rows in the
table that follows the header_row. # for each row we collect the
elements at the same positions as the header_nodes. # this is what we
finally return from the method. (header_row.index_in_parent+1 ..
table.elements.size).collect do |inx| row = table.elements[inx]
header_nodes.collect { |n| row.elements[ n.index_in_parent ].text }
end end</example></p>
</subsection>
<subsection title="Conclusion">
<p>This isn't everything there is to REXML, but it should be enough to
get started. Check the <link href="../doc/index.html">API
documentation</link><footnote>You must generate the API documentation
with rdoc or download the API documentation from the REXML website for
this documentation.</footnote> for particulars and more examples.
There are plenty of unit tests in the <code>test/</code> directory,
and these are great sources of working examples.</p>
</subsection>
</general>
</overview>
<credits>
<p>Among the people who've contributed to this document are:</p>
<list>
<item><link href="mailto:deicher@sandia.gov">Eichert, Diana</link> (bug
fix)</item>
</list>
</credits>
</documentation>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" ?>
<root a="1" _a="2">
<b>1</b>
<_b>2</_b>
</root>

42
test/rexml/data/web.xml Normal file
View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app>
<servlet>
<servlet-name>snoop</servlet-name>
<servlet-class>SnoopServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>file</servlet-name>
<servlet-class>ViewFile</servlet-class>
<init-param>
<param-name>initial</param-name>
<param-value>
1000
</param-value>
<description>
The initial value for the counter <!-- optional -->
</description>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>
mv
</servlet-name>
<url-pattern>
*.wm
</url-pattern>
</servlet-mapping>
<distributed/>
<security-role>
<role-name>
manager
</role-name>
<role-name>
director
</role-name>
<role-name>
president
</role-name>
</security-role>
</web-app>

7
test/rexml/data/web2.xml Normal file
View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<b>
<d />
</b>
<c />
</root>

202
test/rexml/data/working.rss Normal file
View file

@ -0,0 +1,202 @@
<?xml version="1.0"?>
<rss version="0.92">
<channel>
<title>Paul Duncan</title>
<link>http://www.paulduncan.org/</link>
<description>Paul Duncan's personal blog.</description>
</channel>
<item>
<title>Fun With Tense
</title>
<date>Wed Sep 3 19:37:18 2003</date>
<creator>paul@paulduncan.org</creator>
<link>http://www.paulduncan.org/?id=23</link>
<description>
&lt;pre&gt;
&amp;lt;richlowe&amp;gt; blah.
&amp;lt;richlowe&amp;gt; that's what I say.
&amp;lt;pabs&amp;gt; if i say it too then what happens?
&amp;lt;richlowe&amp;gt; then &quot;that's what we say&quot;
&amp;lt;richlowe&amp;gt; duh.
&amp;lt;pabs&amp;gt; what if i say it, then retract it?
&amp;lt;richlowe&amp;gt; Did they teach you nothing in school!
&amp;lt;richlowe&amp;gt; &quot;that's what I say, and he said&quot;
&amp;lt;pabs&amp;gt; :(
&amp;lt;pabs&amp;gt; okay what if i say it, retract it, but then plan on saying it
again at some point in the indeterminite future?
&amp;lt;richlowe&amp;gt; &quot;that's what I say, and he has said, and will possibly say
again&quot;?
&amp;lt;pabs&amp;gt; see now that's not concise at all
&lt;/pre&gt;
</description>
</item>
<item>
<title>We'll Miss You, Michael
</title>
<date>Mon Aug 25 09:52:41 2003</date>
<creator>paul@paulduncan.org</creator>
<link>http://www.paulduncan.org/?id=22</link>
<description>
&lt;p&gt;
Perhaps &lt;a href='http://www.dash-dash.org/pix/death.jpg'&gt;the image&lt;/a&gt;
on &lt;a href='http://www.dash-dash.org/'&gt;his site&lt;/a&gt; was a bit more
fitting than we realized. I'm frustrated that nothing and noone around
him could help ease the pain that he was going through. We can take
comfort in knowing that he felt the decision he made was best for him.
We'll miss you, Michael.
&lt;/p&gt;
</description>
</item>
<item>
<title>Horis, Isis, Osiris, Oh My!
</title>
<date>Fri Aug 22 22:39:23 2003</date>
<creator>paul@paulduncan.org</creator>
<link>http://www.paulduncan.org/?id=21</link>
<description>
&lt;p&gt;
I started reading one of the several mythology books I checked out
earlier this week (as part of a personal research project, the results
of which will be available here eventually). I've only made it through
about 60 pages of Egyptian mythology so far, but it's interesting stuff.
One thing that's impressive to me is how the sexes appear to be on much
more equal footing (as compared to the Judeo/Christian mythology we've
been innundated with for most of our lives). For example, Isis revives
her husband Osiris by collecting his body parts, which are scattered
throughout Egypt. She also saves her son Horus from death and nurtures
him until he can fend for himself. Really interesting stuff. Anyway,
I'll have more about the project as I get farther along.
&lt;/p&gt;
</description>
</item>
<item>
<title>Nature Sucks
</title>
<date>Fri Aug 22 08:33:41 2003</date>
<creator>paul@paulduncan.org</creator>
<link>http://www.paulduncan.org/?id=20</link>
<description>
&lt;p&gt;
&lt;a href='http://www.linuxbrit.co.uk/'&gt;Tom&lt;/a&gt; has been having a rough
couple of weeks. Apparently he's got &lt;a
href='http://www.ninds.nih.gov/health_and_medical/disorders/bells_doc.htm'&gt;Bell's
Palsy&lt;/a&gt; (link from ljlane), which, while treatable and rarely
permanent, still leaves his face partially paralyzed. If you have a few
minutes, you might consider sending him an &lt;abbr title='Electronic
Card'&gt;E-Card&lt;/abbr&gt; or an &lt;a
href='mailto:dr_spock@linuxbrit.co.uk'&gt;email&lt;/a&gt;.
&lt;/p&gt;
</description>
</item>
<item>
<title>Or Maybe He Does
</title>
<date>Thu Aug 21 23:45:40 2003</date>
<creator>paul@paulduncan.org</creator>
<link>http://www.paulduncan.org/?id=19</link>
<description>
&lt;p&gt;
Okay, apparently Ed &lt;em&gt;does&lt;/em&gt; read this page. :-D
&lt;/p&gt;
</description>
</item>
<item>
<title>Ed Got Married!!
</title>
<date>Thu Aug 21 15:52:34 2003</date>
<creator>paul@paulduncan.org</creator>
<link>http://www.paulduncan.org/?id=18</link>
<description>
&lt;p&gt;
Ed got married in the Bahamas! Here's a picture from the honeymoon:
&lt;/p&gt;
&lt;img src='/files/ed_dolphin.jpg' width='252' height='288'
title='Ed on his honeymoon!' alt='Ed on his honeymoon!' /&gt;
&lt;p&gt;
(Fortunately he doesn't read this site).
&lt;/p&gt;
&lt;p&gt;
One other thing. I weigh 186&lt;abbr title='Pounds'&gt;lbs&lt;/abbr&gt; now.
The &lt;a href='http://www.pablotron.org/weight/'&gt;weight page&lt;/a&gt; has been
updated.
&lt;/p&gt;
</description>
</item>
<item>
<title>Gratuitous Douglas Adams Reference, #32427!
</title>
<date>Tue Aug 19 08:25:42 2003</date>
<creator>paul@paulduncan.org</creator>
<link>http://www.paulduncan.org/?id=17</link>
<description>
&lt;p&gt;
Just saw this &lt;acronym title='Uniform Resource Locator'&gt;URL&lt;/acronym&gt;
on &lt;a href='http://www.diveintomark.org/'&gt;Dive Into
Mark&lt;/a&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;a
href='http://www.google.com/search?q=answer+to+life+the+universe+and+everything'&gt;http://www.google.com/search?q=answer+to+life+the+universe+and+everything&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href='http://www.bbc.co.uk/h2g2/guide/'&gt;&lt;acronym title='Hitchhikers
Guide to the Galaxy'&gt;H2G2&lt;/acronym&gt;&lt;/a&gt; references never get old for me.
&lt;/p&gt;
</description>
</item>
<item>
<title>Weekend Update, sans Norm McDonald
</title>
<date>Tue Aug 19 08:18:32 2003</date>
<creator>paul@paulduncan.org</creator>
<link>http://www.paulduncan.org/?id=16</link>
<description>
&lt;p&gt;
What a nutty weekend. A friend of mine went to the &lt;acronym
title='Emergency Room'&gt;ER&lt;/acronym&gt; on Friday night, so I spent 4 hours
down there. It's really frustrating to see that many sick and injured
people in once place, and not really be able to do anything about it.
Also, for that much chaos, both the atmosphere and the staff are
disturbingly calm.
&lt;/p&gt;
&lt;p&gt;
I finally got &lt;a href='http://www.raggle.org/'&gt;Raggle&lt;/a&gt; to a point
worthy of a new release. I'm not going to blather on about the new
stuff; if you're interested you can &lt;a
href='http://www.raggle.org/'&gt;check it out&lt;/a&gt; on your own.
&lt;/p&gt;
&lt;p&gt;
&lt;a href='http://www.pablotron.org/weight/'&gt;The war against obesity&lt;/a&gt;
continues! I'm down to 188 pounds now, a total of 75 pounds lost since
the beginning of March. I've been having trouble losing these last 10
pounds, so this week is officially &quot;Go to the Gym Every Night or Else&quot;
week. 2 days down, 5 to go.
&lt;/p&gt;
</description>
</item>
</rss>

View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<intranet>
<position><aktuell datum="01-10-11">Technik</aktuell></position>
<hauptspalte>
<headline>Technik</headline>
Die Technik ist das Rückgrat der meisten Geschäftsprozesse bei Home of the Brave. Deshalb sollen hier alle relevanten technischen Abläufe, Daten und Einrichtungen beschrieben werden, damit jeder im Bedarfsfall die nötigen Informationen, Anweisungen und Verhaltensempfehlungen nachlesen und/oder abrufen kann.
</hauptspalte>
<nebenspalte>
<link ziel="Flash/">Flash</link><umbruch/>
Nützliches von Flashern für Flasher.<umbruch/>
<link neu="ja" ziel="Cvs/">CVS-FAQ</link><umbruch/>
FAQ zur Benutzung von CVS bei HOB
</nebenspalte>
</intranet>

27
test/rexml/data/xp.tst Normal file
View file

@ -0,0 +1,27 @@
/
/rss
//rss
/rss/channel
//link
//image/*
//link[2]
//link[last()]
rss/channel/link[last()]
rss/channel/item/link[last()]
rss/channel/item/link[1]
rss/channel/item[@x='1']
rss/channel/item[@x]
//item[@x]
//item[normalize-space(@name)='x']
//*[count(title)=1]
//*[name()='link']
//*[starts-with(name(),'li')]
//*[contains(name(),'y')]
//*[string-length(name()) = 4]
//copyright | //title
/child::rss
/descendant::*
//language/parent::*
/rss/channel/ancestor::*
//item[position() mod 2 = 0 ]
//item/ancestor::*

80
test/rexml/data/yahoo.xml Normal file
View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Yahoo! News Search Results for market]]></title>
<link>http://news.search.yahoo.com/search/news?p=market&amp;ei=UTF-8</link>
<description><![CDATA[Yahoo! News Search Results for market]]></description>
<language>en-us</language>
<copyright>Copyright (c) 2004 Yahoo! Inc. All rights reserved.</copyright>
<lastBuildDate>Sun, 03 Sep 2006 16:34:54 GMT</lastBuildDate>
<ttl>5</ttl>
<image>
<title>Yahoo! News</title>
<width>142</width>
<height>18</height>
<link>http://news.search.yahoo.com/news</link>
<url>http://us.i1.yimg.com/us.yimg.com/i/us/nws/th/main_142.gif</url>
</image>
<incremental xmlns="http://purl.org/syndication/history/1.0">false</incremental><item>
<title><![CDATA[Toyota increases share in US auto market (Manila Bulletin)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=13ck33lrk/*http%3A//www.mb.com.ph/archive_pages.php?url=http://www.mb.com.ph/issues/2006/09/04/BSNS2006090473427.html</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=13ck33lrk/*http%3A//www.mb.com.ph/archive_pages.php?url=http://www.mb.com.ph/issues/2006/09/04/BSNS2006090473427.html</guid>
<pubDate>Sun, 03 Sep 2006 16:21:30 GMT</pubDate>
<description><![CDATA[DETROIT (AP) — With a model lineup that consumers love, Toyota Motor Corp. continued to take market share from other automakers last month, posting an industry-best 17 percent increase in sales.]]></description>
</item><item>
<title><![CDATA[ANALYSIS - North Korea finds market for missiles shrinking (Reuters via Yahoo! Asia News)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=11ibfq78e/*http%3A//asia.news.yahoo.com/060903/3/2pd1j.html</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=11ibfq78e/*http%3A//asia.news.yahoo.com/060903/3/2pd1j.html</guid>
<pubDate>Sun, 03 Sep 2006 08:37:33 GMT</pubDate>
<description><![CDATA[ SEOUL (Reuters) - The missile market is not what it used to be for North Korea, with fewer buyers for a key export product and a loss in prestige when its top-end rocket fizzled after a short test flight, U.S. officials and experts said.]]></description>
</item><item>
<title><![CDATA[Broward labor market's a solid performer (Miami Herald)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=13671c2t8/*http%3A//www.miami.com/mld/miamiherald/business/15427113.htm?source=rss&amp;channel=miamiherald_business</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=13671c2t8/*http%3A//www.miami.com/mld/miamiherald/business/15427113.htm?source=rss&amp;channel=miamiherald_business</guid>
<pubDate>Sun, 03 Sep 2006 07:39:53 GMT</pubDate>
<description><![CDATA[In looking at South Florida's labor market, it's a tale of two cities, with Fort Lauderdale coming out on top, by far, according to an annual Labor Day report by Florida International University's Bruce Nissen.]]></description>
</item><item>
<title><![CDATA[NID to help Jharkhand e-market crafts (Yahoo! India News)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=11hg1j19f/*http%3A//in.news.yahoo.com/060903/43/6780a.html</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=11hg1j19f/*http%3A//in.news.yahoo.com/060903/43/6780a.html</guid>
<pubDate>Sun, 03 Sep 2006 10:02:54 GMT</pubDate>
<description><![CDATA[Ranchi, Sep 3 (IANS) Jharkhand will e-market its indigenous products with the help of National Institute of Design (NID), Ahmedabad.]]></description>
</item><item>
<title><![CDATA[Reinsurance market goes high-tech to predict disasters (The Herald-Tribune)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=12j43rdgp/*http%3A//www.heraldtribune.com/apps/pbcs.dll/article?AID=/20060903/NEWS/609030458</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=12j43rdgp/*http%3A//www.heraldtribune.com/apps/pbcs.dll/article?AID=/20060903/NEWS/609030458</guid>
<pubDate>Sun, 03 Sep 2006 10:34:36 GMT</pubDate>
<description><![CDATA[Hurricane outlooks are closely watched at such places as the Lloyd's of London insurance market building.]]></description>
</item><item>
<title><![CDATA[Government warned against going into property market (Sunday Business Post)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=12pru5k6v/*http%3A//www.sbpost.ie/breakingnews/breaking_story.asp?j=4126020&amp;p=4yz6x35&amp;n=4126112&amp;x=</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=12pru5k6v/*http%3A//www.sbpost.ie/breakingnews/breaking_story.asp?j=4126020&amp;p=4yz6x35&amp;n=4126112&amp;x=</guid>
<pubDate>Sun, 03 Sep 2006 09:31:34 GMT</pubDate>
<description><![CDATA[A new report is expected to warn the Government not to intervene in the property market. The report by IIB Bank, which is due to be published tomorrow, will argue that it doesn't make sense for the Government to try and stop speculators buying new homes for profit.]]></description>
</item><item>
<title><![CDATA[Farmers Market gets shoulder-to-shoulder crowds on Saturdays (Great Falls Tribune)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=12pfls0n1/*http%3A//www.greatfallstribune.com/apps/pbcs.dll/article?AID=/20060903/NEWS01/609030306</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=12pfls0n1/*http%3A//www.greatfallstribune.com/apps/pbcs.dll/article?AID=/20060903/NEWS01/609030306</guid>
<pubDate>Sun, 03 Sep 2006 11:12:36 GMT</pubDate>
<description><![CDATA[The produce is bountiful at the Great Falls Farmers Market and so are the customers, vendors say. "Business is booming," said Heather Sands of Little Creek Nursery in Fort Shaw.]]></description>
</item><item>
<title><![CDATA[City Hall takes Plan B for SF market rehab (Sun Star)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=138rfnhvi/*http%3A//www.sunstar.com.ph/static/pam/2006/09/03/news/city.hall.takes.plan.b.for.sf.market.rehab.html</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=138rfnhvi/*http%3A//www.sunstar.com.ph/static/pam/2006/09/03/news/city.hall.takes.plan.b.for.sf.market.rehab.html</guid>
<pubDate>Sun, 03 Sep 2006 08:18:46 GMT</pubDate>
<description><![CDATA[CITY OF SAN FERNANDO -- The City Government here shelved an earlier proposal of constructing the old public market through a bond flotation scheme and instead took Plan B, which is the rehabilitation of the market's wet section.]]></description>
</item><item>
<title><![CDATA[Market watch (AG Weekly)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=12ahobgi6/*http%3A//www.agweekly.com/articles/2006/09/02/news/markets/markets01.txt</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=12ahobgi6/*http%3A//www.agweekly.com/articles/2006/09/02/news/markets/markets01.txt</guid>
<pubDate>Sun, 03 Sep 2006 04:20:37 GMT</pubDate>
<description><![CDATA[The Market Sentiment Index can be an invaluable tool in forecasting important price tops and bottoms in the market. The index was developed by Market Vane, a California-based research company, in the 1960s and is still published by a variety of reliable sources.]]></description>
</item><item>
<title><![CDATA[Catholic War Vets Ladies Club sets flea market (Times Leader)]]></title>
<link>http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=1383flil1/*http%3A//www.timesleader.com/mld/timesleader/living/15431391.htm?source=rss&amp;channel=timesleader_living</link>
<guid isPermaLink="false">http://us.rd.yahoo.com/dailynews/rss/search/market/SIG=1383flil1/*http%3A//www.timesleader.com/mld/timesleader/living/15431391.htm?source=rss&amp;channel=timesleader_living</guid>
<pubDate>Sun, 03 Sep 2006 07:07:50 GMT</pubDate>
<description><![CDATA[Catholic War Veterans, Post 274, Ashley, Ladies Club will hold a flea market from 7 a.m. until 2 p.m. Sept. 10, Sept. 24 and Oct. 1 on the grounds of the Catholic War Veterans. The event will take place rain or shine. For more information, vendor information or to reserve a table, call Marsha Panetta at 823-6232 or Dorothy Liberaski at 474-9969. From left, members of the planning committee are ]]></description>
</item></channel>
</rss>
<!-- s8.news.dcn.yahoo.com uncompressed/chunked Sun Sep 3 09:34:54 PDT 2006 -->

50
test/rexml/listener.rb Normal file
View file

@ -0,0 +1,50 @@
class Listener
attr_reader :ts, :te
attr_reader :normalize
def initialize
@ts = false
@te = false
end
def tag_start name, attrs
@ts = true if name=="subsection" and attrs["title"]=="Namespaces"
end
def tag_end name
@te = true if name=="documentation"
end
def text text
@normalize = text
#text.tr! "\n", ' '
#puts "text #{text[0..10]}..."
end
def instruction name, instruction
#puts "instruction"
end
def comment comment
#puts "comment #{comment[0..10]}..."
end
def doctype name, pub_sys, long_name, uri
#puts "doctype #{name}"
end
def attlistdecl content
#puts "attlistdecl"
end
def elementdecl content
#puts "elementdecl"
end
def entitydecl content
#puts "entitydecl"
end
def notationdecl content
#puts "notationdecl"
end
def entity content
#puts "entity"
end
def cdata content
#puts "cdata"
end
def xmldecl version, encoding, standalone
#puts "xmldecl #{version}"
end
end

View file

@ -0,0 +1,198 @@
require 'test/unit/testcase'
require 'rexml/document'
class AttributesTester < Test::Unit::TestCase
include REXML
def test_accessor
doc = Document.new("<a xmlns:foo='a' xmlns:bar='b' foo:att='1' bar:att='2' att='3'/>")
assert_equal '3', doc.root.attributes['att']
assert_equal '2', doc.root.attributes['bar:att']
doc.root.attributes['att'] = 5
assert_equal '5', doc.root.attributes['att']
end
def test_each_attribute
doc = Document.new('<a x="1" y="2"/>')
doc.root.attributes.each_attribute {|attr|
if attr.expanded_name == 'x'
assert_equal '1', attr.value
elsif attr.expanded_name == 'y'
assert_equal '2', attr.value
else
assert_fail "No such attribute!!"
end
}
end
def test_each
doc = Document.new('<a x="1" y="2"/>')
doc.root.attributes.each {|name, value|
if name == 'x'
assert_equal '1', value
elsif name == 'y'
assert_equal '2', value
else
assert_fail "No such attribute!!"
end
}
end
def test_get_attribute
doc = Document.new('<a xmlns:x="a" x:foo="1" foo="2" bar="3"/>')
assert_equal '2', doc.root.attributes.get_attribute("foo").value
assert_equal '1', doc.root.attributes.get_attribute("x:foo").value
end
def test_size
doc = Document.new("<a xmlns:foo='a' x='1' y='2' foo:x='3'/>")
assert_equal 4, doc.root.attributes.length
end
def test_setter
doc = Document.new("<a xmlns:x='a' x:foo='1' foo='3'/>")
doc.root.attributes['y:foo'] = '2'
assert_equal '2', doc.root.attributes['y:foo']
doc.root.attributes['foo'] = '4'
assert_equal '4', doc.root.attributes['foo']
doc.root.attributes['x:foo'] = nil
assert_equal 3, doc.root.attributes.size
end
def test_delete
doc = Document.new("<a xmlns:y='a' xmlns:x='b' xmlns:z='c' y:foo='0' x:foo='1' foo='3' z:foo='4'/>")
doc.root.attributes.delete 'foo'
assert_equal 6, doc.root.attributes.size
assert_equal '1', doc.root.attributes['x:foo']
doc.root.attributes.delete 'x:foo'
assert_equal 5, doc.root.attributes.size
attr = doc.root.attributes.get_attribute('y:foo')
doc.root.attributes.delete attr
assert_equal 4, doc.root.attributes.size
assert_equal '4', doc.root.attributes['z:foo']
end
def test_prefixes
doc = Document.new("<a xmlns='foo' xmlns:x='bar' xmlns:y='twee' z='glorp' x:k='gru'/>")
prefixes = doc.root.attributes.prefixes
assert_equal 2, prefixes.size
assert_equal 0, (prefixes - ['x', 'y']).size
end
# Contributed by Mike Stok
def test_values_with_apostrophes
doc = Document.new(%q#<tag h1="1'2'" h2='1"2'/>#)
s = doc.to_s
assert(s =~ /h1='1&apos;2&apos;'/)
assert(s =~ /h2='1"2'/)
end
# Submitted by Kou
def test_namespace_conflict
assert_raise( ParseException,
"Declaring two attributes with the same namespace should be an error" ) do
REXML::Document.new <<-XML
<x xmlns:n1="http://www.w3.org"
xmlns:n2="http://www.w3.org" >
<bad n1:a="1" n2:a="2" />
</x>
XML
end
REXML::Document.new("<a xmlns:a='a' xmlns:b='a'></a>")
end
# Submitted by Kou
def test_attribute_deletion
e = REXML::Element.new
e.add_namespace("a", "http://a/")
e.add_namespace("b", "http://b/")
e.add_attributes({"c" => "cc", "a:c" => "cC", "b:c" => "CC"})
e.attributes.delete("c")
assert_nil(e.attributes.get_attribute("c"))
before_size = e.attributes.size
e.attributes.delete("c")
assert_nil(e.attributes.get_attribute("c"))
assert_equal(before_size, e.attributes.size)
e.attributes.delete(e.attributes.get_attribute("a:c"))
assert_nil(e.attributes.get_attribute("a:c"))
e.attributes.delete("b:c")
assert_nil(e.attributes.get_attribute("b:c"))
before_size = e.attributes.size
e.attributes.delete(e.attributes.get_attribute("b:c"))
assert_nil(e.attributes.get_attribute("b:c"))
assert_equal(before_size, e.attributes.size)
before_size = e.attributes.size
e.attributes.delete("c")
assert_nil(e.attributes.get_attribute("c"))
assert_equal(before_size, e.attributes.size)
e.add_attribute("c", "cc")
e.attributes.delete(e.attributes.get_attribute("c"))
assert_nil(e.attributes.get_attribute("c"))
end
# Submitted by Kou
def test_element_usage
attr = Attribute.new("name", "value")
elem = Element.new("elem")
a = Attribute.new(attr, elem)
assert_equal(elem, a.element)
end
def attr_test(attr_name,attr_value)
a1 = REXML::Attribute.new(attr_name,attr_value)
s1 = a1.value
s2 = a1.value
#p s1
#p s2
assert_equal(s1,s2)
a2 = REXML::Attribute.new(attr_name,attr_value)
a2.to_s # NB invocation of to_s
s1 = a2.value
s2 = a2.value
#p s1
#p s2
assert_equal(s1,s2)
end
def test_amp_attributes
attr_test('name','value with &amp; ampersand only')
end
def test_amp_and_lf_attributes
attr_test('name','value with LF &#x000a; &amp; ampersand')
end
def test_quoting
d = Document.new(%q{<a x='1' y="2"/>})
assert_equal( %q{<a x='1' y='2'/>}, d.to_s )
d.root.context[:attribute_quote] = :quote
assert_equal( %q{<a x="1" y="2"/>}, d.to_s )
d = Document.new(%q{<a x='1' y="2"><b z='3'/></a>})
assert_equal( %q{<a x='1' y='2'><b z='3'/></a>}, d.to_s )
d.root.context[:attribute_quote] = :quote
assert_equal( %q{<a x="1" y="2"><b z="3"/></a>}, d.to_s )
end
def test_ticket_127
doc = Document.new
doc.add_element 'a', { 'v' => 'x & y' }
assert doc.to_s.index(';')
end
end

View file

@ -0,0 +1,34 @@
#! /usr/local/bin/ruby
require 'test/unit'
require 'rexml/document'
class TestAttributes < Test::Unit::TestCase
def setup
@ns_a = "urn:x-test:a"
@ns_b = "urn:x-test:b"
element_string = <<-"XMLEND"
<test xmlns:a="#{@ns_a}"
xmlns:b="#{@ns_b}"
a = "1"
b = '2'
a:c = "3"
a:d = '4'
a:e = "5"
b:f = "6"/>
XMLEND
@attributes = REXML::Document.new(element_string).root.attributes
end
def test_get_attribute_ns
assert_equal("1", @attributes.get_attribute_ns("", "a").value)
assert_equal("2", @attributes.get_attribute_ns("", "b").value)
assert_equal("3", @attributes.get_attribute_ns(@ns_a, "c").value)
assert_equal("4", @attributes.get_attribute_ns(@ns_a, "d").value)
assert_equal("5", @attributes.get_attribute_ns(@ns_a, "e").value)
assert_equal("6", @attributes.get_attribute_ns(@ns_b, "f").value)
end
end

View file

@ -0,0 +1,46 @@
#!/usr/bin/ruby -Ku
# -*- coding: utf-8 -*-
require 'kconv'
require 'iconv'
require 'rexml/encoding'
class ChangingEncodings < Test::Unit::TestCase
def initialize a
@u = 'テスト ほげ ふが 美しい'
@e = Kconv.toeuc(@u)
@f = Foo.new
super
end
class Foo
include REXML::Encoding
end
# Note that these tests must be executed in order for the third one to
# actually test anything.
def test_0_euc
@f.encoding = 'EUC-JP'
assert_equal( @u, @f.decode(@e) )
# This doesn't happen anymore, for some reason
#assert_raises( Iconv::IllegalSequence, "Decoding unicode should fail" ) {
# @f.decode(@u) == @u
#}
end
def test_1_utf
@f.encoding = 'UTF-8'
assert_not_equal( @u, @f.decode( @e ) )
assert_equal( @u, @f.decode( @u ) )
end
def test_2_euc
@f.encoding = 'EUC-JP'
assert_equal( @u, @f.decode(@e) )
# This doesn't happen anymore, for some reason
#assert_raises( Iconv::IllegalSequence, "Decoding unicode should fail" ) {
# @f.decode(@u) == @u
#}
end
end

581
test/rexml/test_contrib.rb Normal file
View file

@ -0,0 +1,581 @@
# coding: binary
require "test/unit/testcase"
require "rexml/document"
require "rexml/parseexception"
require "rexml/formatters/default"
class ContribTester < Test::Unit::TestCase
include REXML
XML_STRING_01 = <<DELIMITER
<?xml version="1.0" encoding="UTF-8"?>
<biblio>
<entry type="Book">
<author>Thomas, David; Hunt, Andrew</author>
<language>english</language>
<publisher>Addison-Wesley</publisher>
<title>Programming Ruby. The Pragmatic Programmer's Guide</title>
<year>2000</year>
</entry>
<entry type="Book">
<author>Blammo, Blah</author>
<language>english</language>
<publisher>Hubbabubba</publisher>
<title>Foozboozer's Life</title>
<type>Book</type>
<year>2002</year>
</entry>
</biblio>
DELIMITER
XML_STRING_02 = <<DELIMITER
<biblio>
<entry type="Book">
<language>english</language>
<publisher>Addison-Wesley</publisher>
<title>Programming Ruby. The Pragmatic Programmer's Guide</title>
<type>Book</type>
<year>2000</year>
</entry>
<entry type="Book">
<author>Blammo, Blah</author>
<language>english</language>
<publisher>Hubbabubba</publisher>
<title>Foozboozer's Life</title>
<type>Book</type>
<year>2002</year>
</entry>
</biblio>
DELIMITER
# Tobias Reif <tobiasreif@pinkjuice.com>
def test_bad_doctype_Tobias
source = <<-EOF
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN"
"http://www.w3.org/TR/SVG/DTD/svg10.dtd"
[
<!-- <!ENTITY % fast-slow "0 0 .5 1">-->
<!--<!ENTITY % slow-fast ".5 0 1 1">-->
<!ENTITY hover_ani
'<animateTransform attributeName="transform"
type="scale" restart="whenNotActive" values="1;0.96"
dur="0.5s" calcMode="spline" keySplines="0 0 .5 1"
fill="freeze" begin="mouseover"/>
<animateTransform attributeName="transform"
type="scale" restart="whenNotActive" values="0.96;1"
dur="0.5s" calcMode="spline" keySplines=".5 0 1 1"
fill="freeze" begin="mouseover+0.5s"/>'
>
]
>
EOF
doc = REXML::Document.new source
doc.write(out="")
assert(out[/>'>/] != nil, "Couldn't find >'>")
assert(out[/\]>/] != nil, "Couldn't find ]>")
end
# Peter Verhage
def test_namespace_Peter
source = <<-EOF
<?xml version="1.0"?>
<config:myprog-config xmlns:config="http://someurl/program/version">
<!-- main options -->
<config:main>
<config:parameter name="name" value="value"/>
</config:main>
</config:myprog-config>
EOF
doc = REXML::Document.new source
assert_equal "myprog-config", doc.root.name
count = 0
REXML::XPath.each(doc, "x:myprog-config/x:main/x:parameter",
{"x"=>"http://someurl/program/version"}) { |element|
assert_equal "name", element.attributes["name"]
count += 1;
}
assert_equal 1, count
assert_equal "myprog-config", doc.elements["config:myprog-config"].name
end
# Tobias Reif <tobiasreif@pinkjuice.com>
def test_complex_xpath_Tobias
source = <<-EOF
<root>
<foo>
<bar style="baz"/>
<blah style="baz"/>
<blam style="baz"/>
</foo>
<wax>
<fudge>
<noodle/>
</fudge>
</wax>
</root>
EOF
# elements that have child elements
# but not grandchildren
# and not children that don't have a style attribute
# and not children that have a unique style attribute
complex_path = "*[* "+
"and not(*/node()) "+
"and not(*[not(@style)]) "+
"and not(*/@style != */@style)]"
doc = REXML::Document.new source
results = REXML::XPath.match( doc.root, complex_path )
assert(results)
assert_equal 1, results.size
assert_equal "foo", results[0].name
end
# "Chris Morris" <chrismo@charter.net>
def test_extra_newline_on_read_Chris
text = 'test text'
e = REXML::Element.new('Test')
e.add_text(text)
REXML::Formatters::Default.new.write(e,out="")
doc = REXML::Document.new(out)
outtext = doc.root.text
assert_equal(text, outtext)
end
# Tobias Reif <tobiasreif@pinkjuice.com>
def test_other_xpath_Tobias
schema = <<-DELIM
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="rect">
<xs:complexType>
<xs:attribute name="width" type="xs:byte" use="required"/>
<xs:attribute name="height" type="xs:byte" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="svg">
<xs:complexType>
<xs:sequence>
<xs:element ref="rect"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
DELIM
doc = REXML::Document.new schema
result = REXML::XPath.first(doc.root, 'xs:element[descendant::xs:element[@ref]]')
assert result
assert_equal "svg", result.attributes['name']
result = REXML::XPath.first(doc, 'element[descendant::element[@ref]]')
assert_nil result
end
#this first test succeeds, to check if stuff is set up correctly
def test_xpath_01_TobiasReif
doc = Document.new XML_STRING_01.dup
desired_result = Document.new '<author>Thomas, David; Hunt, Andrew</author>'
xpath = '//author'
result = XPath.first(doc, xpath)
assert_equal desired_result.to_s, result.to_s
end
def test_xpath_whitespace_TobiasReif
# same as above, with whitespace in XPath
doc = Document.new(XML_STRING_01.dup)
desired_result = Document.new('<author>Thomas, David; Hunt, Andrew</author>')
xpath = "\/\/author\n \n"
result = XPath.first(doc, xpath)
failure_message = "\n[[[TR: AFAIK, whitespace should be allowed]]]\n"
assert_equal(desired_result.to_s, result.to_s, failure_message)
end
def test_xpath_02_TobiasReif
doc = Document.new XML_STRING_01.dup
desired_result = Document.new '<author>Thomas, David; Hunt, Andrew</author>'
# Could that quirky
# Programmer',&quot;'&quot;,'s
# be handled automatically, somehow?
# Or is there a simpler way? (the below XPath should match the author element above,
# AFAIK; I tested it inside an XSLT)
xpath = %q{/biblio/entry[
title/text()=concat('Programming Ruby. The Pragmatic Programmer',"'",'s Guide')
and
year='2000'
]/author}
result = XPath.first(doc, xpath)
failure_message = "\nHow to handle the apos inside the string inside the XPath?\nXPath = #{xpath}\n"
assert_equal desired_result.to_s, result.to_s, failure_message
end
def test_xpath_03_TobiasReif
doc = Document.new XML_STRING_02.dup
desired_result_string = "<entry type='Book'>
<language>english</language>
<publisher>Addison-Wesley</publisher>
<title>Programming Ruby. The Pragmatic Programmer's Guide</title>
<type>Book</type>
<year>2000</year>
</entry>"
desired_result_tree = Document.new desired_result_string
xpath = "/biblio/entry[not(author)]"
result = XPath.first(doc, xpath)
assert_equal desired_result_string, result.to_s
end
def test_umlaut
koln_iso = "K\xf6ln"
koln_utf = "K\xc3\xb6ln"
source_iso = "<?xml version='1.0' encoding='ISO-8859-1'?><test>#{koln_iso}</test>"
source_utf = "<?xml version='1.0' encoding='UTF-8'?><test>#{koln_utf}</test>"
if String.method_defined? :encode
koln_iso.force_encoding('iso-8859-1')
koln_utf.force_encoding('utf-8')
source_iso.force_encoding('iso-8859-1')
source_utf.force_encoding('utf-8')
end
doc = REXML::Document.new(source_iso)
assert_equal('ISO-8859-1', doc.xml_decl.encoding)
assert_equal(koln_utf, doc.root.text)
doc.write(out="")
assert_equal(source_iso, out )
doc.xml_decl.encoding = 'UTF-8'
doc.write(out="")
assert_equal(source_utf, out)
doc = Document.new <<-EOF
<?xml version="1.0" encoding="ISO-8859-1"?>
<intranet>
<position><aktuell datum="01-10-11">Technik</aktuell></position>
<hauptspalte>
<headline>Technik</headline>
Die Technik ist das Rückgrat der meisten Geschäftsprozesse bei Home of the Brave. Deshalb sollen hier alle relevanten technischen Abläufe, Daten und Einrichtungen beschrieben werden, damit jeder im Bedarfsfall die nötigen Informationen, Anweisungen und Verhaltensempfehlungen nachlesen und/oder abrufen kann.
</hauptspalte>
<nebenspalte>
<link ziel="Flash/">Flash</link><umbruch/>
Nützliches von Flashern für Flasher.<umbruch/>
<link neu="ja" ziel="Cvs/">CVS-FAQ</link><umbruch/>
FAQ zur Benutzung von CVS bei HOB
</nebenspalte>
</intranet>
EOF
tn = XPath.first(doc, "//nebenspalte/text()[2]")
expected_iso = "Nützliches von Flashern für Flasher."
expected_utf = expected_iso.unpack('C*').pack('U*')
if expected_utf.respond_to? :encode
expected_iso.force_encoding("iso-8859-1")
expected_utf.force_encoding(Encoding::UTF_8)
end
assert_equal(expected_utf, tn.to_s.strip)
f = REXML::Formatters::Default.new
f.write( tn, Output.new(o = "", "ISO-8859-1") )
assert_equal(expected_iso, o.strip)
doc = Document.new File.new('test/data/xmlfile-bug.xml')
tn = XPath.first(doc, "//nebenspalte/text()[2]")
assert_equal(expected_utf, tn.to_s.strip)
f.write( tn, Output.new(o = "", "ISO-8859-1") )
assert_equal(expected_iso, o.strip)
end
def test_element_cloning_namespace_Chris
aDoc = REXML::Document.new '<h1 tpl:content="title" xmlns:tpl="1">Dummy title</h1>'
anElement = anElement = aDoc.elements[1]
elementAttrPrefix = anElement.attributes.get_attribute('content').prefix
aClone = anElement.clone
cloneAttrPrefix = aClone.attributes.get_attribute('content').prefix
assert_equal( elementAttrPrefix , cloneAttrPrefix )
end
def test_namespaces_in_attlist_tobias
in_string = File.open('test/data/foo.xml', 'r') do |file|
file.read
end
doc = Document.new in_string
assert_nil XPath.first(doc,'//leg')
assert_equal 'http://www.foo.com/human', doc.root.elements[1].namespace
assert_equal 'human leg',
XPath.first(doc, '//x:leg/text()', {'x'=>'http://www.foo.com/human'}).to_s
end
# Alun ap Rhisiart
def test_less_than_in_element_content
source = File.new('test/data/ProductionSupport.xml')
h = Hash.new
doc = REXML::Document.new source
doc.elements.each("//CommonError") { |el|
h[el.elements['Key'].text] = 'okay'
}
assert(h.include?('MotorInsuranceContract(Object)>>#error:'))
end
# XPaths provided by Thomas Sawyer
def test_various_xpath
#@doc = REXML::Document.new('<r a="1"><p><c b="2"/></p></r>')
doc = REXML::Document.new('<r a="1"><p><c b="2">3</c></p></r>')
[['/r', REXML::Element],
['/r/p/c', REXML::Element],
['/r/attribute::a', Attribute],
['/r/@a', Attribute],
['/r/attribute::*', Attribute],
['/r/@*', Attribute],
['/r/p/c/attribute::b', Attribute],
['/r/p/c/@b', Attribute],
['/r/p/c/attribute::*', Attribute],
['/r/p/c/@*', Attribute],
['//c/attribute::b', Attribute],
['//c/@b', Attribute],
['//c/attribute::*', Attribute],
['//c/@*', Attribute],
['.//node()', REXML::Node ],
['.//node()[@a]', REXML::Element ],
['.//node()[@a="1"]', REXML::Element ],
['.//node()[@b]', REXML::Element ], # no show, why?
['.//node()[@b="2"]', REXML::Element ]
].each do |xpath,kind|
begin
REXML::XPath.each( doc, xpath ) do |what|
assert_kind_of( kind, what, "\n\nWrong type (#{what.class}) returned for #{xpath} (expected #{kind.name})\n\n" )
end
rescue Exception
puts "PATH WAS: #{xpath}"
raise
end
end
[
['/r', 'attribute::a', Attribute ],
['/r', '@a', Attribute ],
['/r', 'attribute::*', Attribute ],
['/r', '@*', Attribute ],
['/r/p/c', 'attribute::b', Attribute ],
['/r/p/c', '@b', Attribute ],
['/r/p/c', 'attribute::*', Attribute ],
['/r/p/c', '@*', Attribute ]
].each do |nodepath, xpath, kind|
begin
context = REXML::XPath.first(doc, nodepath)
REXML::XPath.each( context, xpath ) do |what|
assert_kind_of kind, what, "Wrong type (#{what.class}) returned for #{xpath} (expected #{kind.name})\n"
end
rescue Exception
puts "PATH WAS: #{xpath}"
raise
end
end
end
def test_entities_Holden_Glova
document = <<-EOL
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rubynet [
<!ENTITY rbconfig.MAJOR "1">
<!ENTITY rbconfig.MINOR "7">
<!ENTITY rbconfig.TEENY "2">
<!ENTITY rbconfig.ruby_version "&rbconfig.MAJOR;.&rbconfig.MINOR;">
<!ENTITY rbconfig.arch "i386-freebsd5">
<!ENTITY rbconfig.prefix "/usr/local">
<!ENTITY rbconfig.libdir "&rbconfig.prefix;/lib">
<!ENTITY rbconfig.includedir "&rbconfig.prefix;/include">
<!ENTITY rbconfig.sitedir "&rbconfig.prefix;/lib/ruby/site_ruby">
<!ENTITY rbconfig.sitelibdir "&rbconfig.sitedir;/&rbconfig.ruby_version;">
<!ENTITY rbconfig.sitearchdir "&rbconfig.sitelibdir;/&rbconfig.arch;">
]>
<rubynet>
<pkg version="version1.0">
<files>
<file>
<filename>uga.rb</filename>
<mode>0444</mode>
<path>&rbconfig.libdir;/rexml</path>
<content encoding="xml">... the file here</content>
</file>
<file>
<filename>booga.h</filename>
<mode>0444</mode>
<path>&rbconfig.includedir;</path>
<content encoding="xml">... the file here</content>
</file>
<file>
<filename>foo.so</filename>
<mode>0555</mode>
<path>&rbconfig.sitearchdir;/rexml</path>
<content encoding="mime64">Li4uIHRoZSBmaWxlIGhlcmU=\n</content>
</file>
</files>
</pkg>
</rubynet>
EOL
file_xpath = '/rubynet/pkg/files/file'
root = REXML::Document.new(document)
root.elements.each(file_xpath) do |metadata|
text = metadata.elements['path'].get_text.value
assert text !~ /&rbconfig/, "'#{text}' failed"
end
#Error occurred in test_package_file_opens(TC_PackageInstall):
# ArgumentError:
#illegal access mode &rbconfig.prefix;/lib/rexml
#
#[synack@Evergreen] src $ ruby --version
#ruby 1.6.7 (2002-03-01) [i686-linux-gnu]
#
#It looks like it expanded the first entity, but didn't reparse it for more
#entities. possible bug - or have I mucked this up?
end
def test_whitespace_after_xml_decl
d = Document.new <<EOL
<?xml version='1.0'?>
<blo>
<wak>
</wak>
</blo>
EOL
end
def test_external_entity
xp = '//channel/title'
%w{data/working.rss data/broken.rss}.each do |path|
File.open(File.join( "test", path )) do |file|
doc = REXML::Document.new file.readlines.join('')
# check to make sure everything is kosher
assert_equal( doc.root.class, REXML::Element )
assert_equal( doc.root.elements.class, REXML::Elements )
# get the title of the feed
assert( doc.root.elements[xp].kind_of?( REXML::Element ) )
end
end
end
def test_maintain_dtd
src = %q{<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ivattacks SYSTEM "../../ivacm.dtd" [
<!ENTITY % extern-packages SYSTEM "../../ivpackages.dtd">
<!ENTITY % extern-packages SYSTEM "../../common-declarations.dtd">
%extern-packages;
%extern-common;
]>}
doc = Document.new( src )
doc.write( out="" )
src = src.tr('"', "'")
out = out.tr('"', "'")
assert_equal( src, out )
end
def test_text_nodes_nomatch
source = "<root><child>test</child></root>"
d = REXML::Document.new( source )
r = REXML::XPath.match( d, %q{/root/child[text()="no-test"]} )
assert_equal( 0, r.size )
end
def test_raw_Terje_Elde
f = REXML::Formatters::Default.new
txt = 'abc&#248;def'
a = Text.new( txt,false,nil,true )
f.write(a,out="")
assert_equal( txt, out )
txt = '<sean><russell>abc&#248;def</russell></sean>'
a = Document.new( txt, { :raw => ["russell"] } )
f.write(a,out="")
assert_equal( txt, out )
end
def test_indenting_error
a=Element.new("test1")
b=Element.new("test2")
c=Element.new("test3")
b << c
a << b
REXML::Formatters::Pretty.new.write(a,s="")
end
def test_pos
testfile = "/tmp/tidal#{$$}"
testdata = %Q{<calibration>
<section name="parameters">
<param name="barpress">760</param>
<param name="hertz">50</param>
</section>
</calibration>
}
File.open(testfile, 'w') do |f|
f.puts testdata
end
File.open(testfile) do |f|
d = REXML::Document.new(f)
end
#File.unlink(testfile)
end
def test_deep_clone
a = Document.new( '<?xml version="1.0"?><!DOCTYPE html PUBLIC
"-//W3C//DTD
XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html
xmlns="http:///www.w3.org/1999/xhtml"></html>' )
b = a.deep_clone
assert_equal a.to_s, b.to_s
end
def test_double_escaping
data = '<title>AT&amp;T</title>'
xml = "<description><![CDATA[#{data}]]></description>"
doc = REXML::Document.new(xml)
description = doc.find {|e| e.name=="description"}
assert_equal data, description.text
end
def test_ticket_12
cfg = "<element><anotherelement><child1>a</child1><child2>b</child2></anotherelement></element>"
config = REXML::Document.new( cfg )
assert_equal( "a", config.elements[ "//child1" ].text )
end
=begin
# This is a silly test, and is low priority
def test_namespace_serialization_tobi_reif
doc = Document.new '<doc xmlns:b="http://www.foo.foo">
<b:p/>
</doc>'
ns = 'http://www.foo.foo'
ns_declaration={'f'=>ns}
returned = XPath.match(doc,'//f:p',ns_declaration)
# passes:
assert( (returned[0].namespace==ns), 'namespace should be '+ns)
serialized = returned.to_s
serialized_and_parsed = Document.new(serialized)
puts 'serialized: '+serialized
# ... currently brings <b:p/>
# prefix b is undeclared (!)
assert( (serialized_and_parsed.namespace==ns),
'namespace should still be '+ns.inspect+
' and not '+serialized_and_parsed.namespace.inspect)
# ... currently results in a failure:
# 'namespace should still be "http://www.foo.foo" and not ""'
end
=end
end

1382
test/rexml/test_core.rb Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,67 @@
#! /usr/local/bin/ruby
require 'test/unit'
require 'rexml/document'
class TestDoctype < Test::Unit::TestCase
def setup
@sysid = "urn:x-test:sysid1"
@notid1 = "urn:x-test:notation1"
@notid2 = "urn:x-test:notation2"
document_string1 = <<-"XMLEND"
<!DOCTYPE r SYSTEM "#{@sysid}" [
<!NOTATION n1 SYSTEM "#{@notid1}">
<!NOTATION n2 SYSTEM "#{@notid2}">
]>
<r/>
XMLEND
@doctype1 = REXML::Document.new(document_string1).doctype
@pubid = "TEST_ID"
document_string2 = <<-"XMLEND"
<!DOCTYPE r PUBLIC "#{@pubid}">
<r/>
XMLEND
@doctype2 = REXML::Document.new(document_string2).doctype
document_string3 = <<-"XMLEND"
<!DOCTYPE r PUBLIC "#{@pubid}" "#{@sysid}">
<r/>
XMLEND
@doctype3 = REXML::Document.new(document_string3).doctype
end
def test_public
assert_equal(nil, @doctype1.public)
assert_equal(@pubid, @doctype2.public)
assert_equal(@pubid, @doctype3.public)
end
def test_system
assert_equal(@sysid, @doctype1.system)
assert_equal(nil, @doctype2.system)
assert_equal(@sysid, @doctype3.system)
end
def test_notation
assert_equal(@notid1, @doctype1.notation("n1").system)
assert_equal(@notid2, @doctype1.notation("n2").system)
end
def test_notations
notations = @doctype1.notations
assert_equal(2, notations.length)
assert_equal(@notid1, find_notation(notations, "n1").system)
assert_equal(@notid2, find_notation(notations, "n2").system)
end
def find_notation(notations, name)
notations.find { |notation|
name == notation.name
}
end
end

107
test/rexml/test_elements.rb Normal file
View file

@ -0,0 +1,107 @@
require 'test/unit/testcase'
require 'rexml/document'
class ElementsTester < Test::Unit::TestCase
include REXML
def test_elements_accessor
doc = Document.new '<a><b/><c id="1"/><c id="2"/><d/></a>'
assert_equal 'b', doc.root.elements[1].name
assert_equal '1', doc.root.elements['c'].attributes['id']
assert_equal '2', doc.root.elements[2,'c'].attributes['id']
end
def test_elements_indexing
doc = Document.new '<a/>'
doc.root.elements[10] = Element.new('b')
assert_equal 'b', doc.root.elements[1].name
doc.root.elements[1] = Element.new('c')
assert_equal 'c', doc.root.elements[1].name
doc.root.elements['c'] = Element.new('d')
assert_equal 'd', doc.root.elements[1].name
end
def test_elements_delete
doc = Document.new '<a><b/><c/><c id="1"/></a>'
block = proc { |str|
out = ''
doc.write out
assert_equal str, out
}
b = doc.root.elements[1]
doc.root.elements.delete b
block.call( "<a><c/><c id='1'/></a>" )
doc.elements.delete("a/c[@id='1']")
block.call( '<a><c/></a>' )
doc.root.elements.delete 1
block.call( '<a/>' )
end
def test_elements_delete_all
doc = Document.new '<a><c/><c/><c/><c/></a>'
deleted = doc.elements.delete_all 'a/c'
assert_equal 4, deleted.size
end
def test_ticket_36
doc = Document.new( "<a xmlns:xi='foo'><b><xi:c id='1'/></b><xi:c id='2'/></a>" )
deleted = doc.root.elements.delete_all( "xi:c" )
assert_equal( 1, deleted.size )
doc = Document.new( "<a xmlns:xi='foo'><b><xi:c id='1'/></b><xi:c id='2'/></a>" )
deleted = doc.root.elements.delete_all( "//xi:c" )
assert_equal( 2, deleted.size )
end
def test_elements_add
a = Element.new 'a'
a.elements.add Element.new('b')
assert_equal 'b', a.elements[1].name
a.elements.add 'c'
assert_equal 'c', a.elements[2].name
end
def test_elements_size
doc = Document.new '<a>sean<b/>elliott<b/>russell<b/></a>'
assert_equal 6, doc.root.size
assert_equal 3, doc.root.elements.size
end
def test_elements_each
doc = Document.new '<a><b/><c/><d/>sean<b/><c/><d/></a>'
count = 0
block = proc {|e| count += 1}
doc.root.elements.each(&block)
assert_equal 6, count
count = 0
doc.root.elements.each('b', &block)
assert_equal 2, count
count = 0
doc.root.elements.each('child::node()', &block)
assert_equal 6, count
count = 0
XPath.each(doc.root, 'child::node()', &block)
assert_equal 7, count
end
def test_elements_to_a
doc = Document.new '<a>sean<b/>elliott<c/></a>'
assert_equal 2, doc.root.elements.to_a.size
assert_equal 2, doc.root.elements.to_a("child::node()").size
assert_equal 4, XPath.match(doc.root, "child::node()").size
end
def test_elements_collect
doc = Document.new( "<a><b id='1'/><b id='2'/></a>" )
r = doc.elements.collect( "/a/b" ) { |e| e.attributes["id"].to_i }
assert_equal( [1,2], r )
end
def test_elements_inject
doc = Document.new( "<a><b id='1'/><b id='2'/></a>" )
r = doc.elements.inject( "/a/b", 3 ) { |s, e|
s + e.attributes["id"].to_i
}
assert_equal 6, r
end
end

View file

@ -0,0 +1,92 @@
# coding: binary
require "test/unit/testcase"
require 'rexml/source'
class EncodingTester < Test::Unit::TestCase
include REXML
TEST_DIR="test/data"
def setup
@encoded = "<?xml version='1.0' encoding='ISO-8859-3'?>"+
"<a><b>\346</b></a>"
@not_encoded = "<a><b>ĉ</b></a>"
end
# Given an encoded document, try to write out to that encoding
def test_encoded_in_encoded_out
doc = Document.new( @encoded )
doc.write( out="" )
out.force_encoding('binary') if out.respond_to? :force_encoding
assert_equal( @encoded, out )
end
# Given an encoded document, try to change the encoding and write it out
def test_encoded_in_change_out
doc = Document.new( @encoded )
doc.xml_decl.encoding = "UTF-8"
assert_equal( doc.encoding, "UTF-8" )
REXML::Formatters::Default.new.write( doc.root, out="" )
out.force_encoding('binary') if out.respond_to? :force_encoding
assert_equal( @not_encoded, out )
char = XPath.first( doc, "/a/b/text()" ).to_s
char.force_encoding('binary') if char.respond_to? :force_encoding
assert_equal( "ĉ", char )
end
# * Given an encoded document, try to write it to a different encoding
def test_encoded_in_different_out
doc = Document.new( @encoded )
REXML::Formatters::Default.new.write( doc.root, Output.new( out="", "UTF-8" ) )
out.force_encoding('binary') if out.respond_to? :force_encoding
assert_equal( @not_encoded, out )
end
# * Given a non-encoded document, change the encoding
def test_in_change_out
doc = Document.new( @not_encoded )
doc.xml_decl.encoding = "ISO-8859-3"
assert_equal( doc.encoding, "ISO-8859-3" )
doc.write( out="" )
out.force_encoding('binary') if out.respond_to? :force_encoding
assert_equal( @encoded, out )
end
# * Given a non-encoded document, write to a different encoding
def test_in_different_out
doc = Document.new( @not_encoded )
doc.write( Output.new( out="", "ISO-8859-3" ) )
out.force_encoding('binary') if out.respond_to? :force_encoding
assert_equal( @encoded, out )
end
# * Given an encoded document, accessing text and attribute nodes
# should provide UTF-8 text.
def test_in_different_access
doc = Document.new <<-EOL
<?xml version='1.0' encoding='ISO-8859-1'?>
<a a="ÿ">ÿ</a>
EOL
expect = "\303\277"
expect.force_encoding('UTF-8') if expect.respond_to? :force_encoding
assert_equal( expect, doc.elements['a'].attributes['a'] )
assert_equal( expect, doc.elements['a'].text )
end
def test_ticket_89
doc = Document.new <<-EOL
<?xml version="1.0" encoding="CP-1252" ?>
<xml><foo></foo></xml>
EOL
REXML::Document.new doc
end
def test_ticket_110
utf16 = REXML::Document.new(File.new(File.join(TEST_DIR,"ticket_110_utf16.xml")))
assert_equal( "UTF-16", utf16.encoding )
assert( utf16[0].kind_of?(REXML::XMLDecl))
end
end

View file

@ -0,0 +1,59 @@
require "test/unit/testcase"
require "rexml/document"
require "rexml/parseexception"
=begin
# THIS DOESN'T WORK
begin
require 'iconv'
UnixCharsets = open("| iconv -l") do |f|
f.readlines[5..-1].collect { |x| x.sub(/\/\/\n/,"").delete(' ') }
end
DATA = <<END
<?xml version="1.0" encoding='ENC'?>
<Ruby xmlns="http://www.ruby-lang.org/ruby/1.8">
</Ruby>
END
class IConvTester < Test::Unit::TestCase
def test_iconv
broken_encodings = 0
UnixCharsets.each do |enc|
begin
puts "Testing encoding #{enc}"
data = DATA.dup
data[/ENC/] = enc
REXML::Document.new(data).root
rescue REXML::ParseException => e
broken_encodings += 1
fail "Encoding #{enc} does not work with REXML: #{e.message}"
rescue Errno::EINVAL => e
broken_encodings += 1
fail "Encoding #{enc} does not work with REXML: #{e.message}"
rescue ArgumentError => e
broken_encodings += 1
fail "Encoding #{enc} does not work with REXML: #{e.message}"
rescue
broken_encodings += 1
fail "Encoding #{enc} does not work with REXML: #{$!.message}"
end
end
if broken_encodings > 0
fail "There were #{broken_encodings} encoding failures out of #{UnixCharsets.size} plus some REXML internal encodings"
else
fail "There were no encoding failures"
end
puts "Full list of registered encodings in REXML:"
puts REXML::Encoding::ENCODING_CLAIMS.values.join(', ')
end
end
rescue LoadError
end
=end

148
test/rexml/test_entity.rb Normal file
View file

@ -0,0 +1,148 @@
require "test/unit/testcase"
require 'rexml/entity'
require 'rexml/source'
class EntityTester < Test::Unit::TestCase
def test_parse_general_decl
simple = "<!ENTITY foo 'bar'>"
simple =~ /#{REXML::Entity::GEDECL}/
assert $&
assert_equal simple, $&
REXML::Entity::ENTITYDECL =~ simple
assert REXML::Entity::matches?(simple)
match = REXML::Entity::ENTITYDECL.match(simple)
assert_equal 'foo', match[1]
assert_equal "'bar'", match[2]
simple = '<!ENTITY Pub-Status
"This is a pre-release of the specification.">'
assert REXML::Entity::matches?(simple)
match = REXML::Entity::ENTITYDECL.match(simple)
assert_equal 'Pub-Status', match[1]
assert_equal '"This is a pre-release of the specification."', match[2]
txt = '"This is a
pre-release of <the> specification."'
simple = "<!ENTITY Pub-Status
#{txt}>"
assert REXML::Entity::matches?(simple)
match = REXML::Entity::ENTITYDECL.match(simple)
assert_equal 'Pub-Status', match[1]
assert_equal txt, match[2]
end
def test_parse_external_decl
zero = '<!ENTITY open-hatch SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml" >'
one = '<!ENTITY open-hatch
SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">'
two = '<!ENTITY open-hatch
PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
"http://www.textuality.com/boilerplate/OpenHatch.xml">'
three = '<!ENTITY hatch-pic
SYSTEM "../grafix/OpenHatch.gif"
NDATA gif >'
assert REXML::Entity::matches?(zero)
assert REXML::Entity::matches?(one)
assert REXML::Entity::matches?(two)
assert REXML::Entity::matches?(three)
end
def test_parse_entity
one = %q{<!ENTITY % YN '"Yes"'>}
two = %q{<!ENTITY WhatHeSaid "He said %YN;">}
assert REXML::Entity::matches?(one)
assert REXML::Entity::matches?(two)
end
def test_constructor
one = [ %q{<!ENTITY % YN '"Yes"'>},
%q{<!ENTITY % YN2 "Yes">},
%q{<!ENTITY WhatHeSaid "He said %YN;">},
'<!ENTITY open-hatch
SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">',
'<!ENTITY open-hatch2
PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
"http://www.textuality.com/boilerplate/OpenHatch.xml">',
'<!ENTITY hatch-pic
SYSTEM "../grafix/OpenHatch.gif"
NDATA gif>' ]
source = %q{<!DOCTYPE foo [
<!ENTITY % YN '"Yes"'>
<!ENTITY % YN2 "Yes">
<!ENTITY WhatHeSaid "He said %YN;">
<!ENTITY open-hatch
SYSTEM "http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY open-hatch2
PUBLIC "-//Textuality//TEXT Standard open-hatch boilerplate//EN"
"http://www.textuality.com/boilerplate/OpenHatch.xml">
<!ENTITY hatch-pic
SYSTEM "../grafix/OpenHatch.gif"
NDATA gif>
]>}
d = REXML::Document.new( source )
dt = d.doctype
c = 0
dt.each do |child|
if child.kind_of? REXML::Entity
str = one[c].tr("\r\n\t", ' ').squeeze(" ")
assert_equal str, child.to_s
c+=1
end
end
end
def test_replace_entities
source = "<!DOCTYPE blah [\n<!ENTITY foo \"bar\">\n]><a>&foo;</a>"
doc = REXML::Document.new(source)
assert_equal 'bar', doc.root.text
out = ''
doc.write out
assert_equal source, out
end
def test_raw
source = '<!DOCTYPE foo [
<!ENTITY ent "replace">
]><a>replace &ent;</a>'
doc = REXML::Document.new( source, {:raw=>:all})
assert_equal('replace &ent;', doc.root.get_text.to_s)
assert_equal(source, doc.to_s)
end
def test_lazy_evaluation
source = '<!DOCTYPE foo [
<!ENTITY ent "replace">
]><a>replace &ent;</a>'
doc = REXML::Document.new( source )
assert_equal(source, doc.to_s)
assert_equal("replace replace", doc.root.text)
assert_equal(source, doc.to_s)
end
# Contributed (not only test, but bug fix!!) by Kouhei Sutou
def test_entity_replacement
source = %q{<!DOCTYPE foo [
<!ENTITY % YN '"Yes"'>
<!ENTITY WhatHeSaid "He said %YN;">]>
<a>&WhatHeSaid;</a>}
d = REXML::Document.new( source )
dt = d.doctype
assert_equal( '"Yes"', dt.entities[ "YN" ].value )
assert_equal( 'He said "Yes"', dt.entities[ "WhatHeSaid" ].value )
assert_equal( 'He said "Yes"', d.elements[1].text )
end
# More unit tests from Kouhei. I looove users who give me unit tests.
def test_entity_insertions
assert_equal("&amp;", REXML::Text.new("&amp;", false, nil, true).to_s)
#assert_equal("&", REXML::Text.new("&amp;", false, false).to_s)
end
def test_single_pass_unnormalization # ticket 123
assert_equal '&amp;&', REXML::Text::unnormalize('&#38;amp;&amp;')
end
end

View file

@ -0,0 +1,223 @@
require "test/unit/testcase"
require "rexml/document"
class FunctionsTester < Test::Unit::TestCase
include REXML
def test_functions
# trivial text() test
# confuse-a-function
source = "<a>more <b id='1'/><b id='2'>dumb</b><b id='3'/><c/> text</a>"
doc = Document.new source
res = ""
XPath::each(doc.root, "text()") {|val| res << val.to_s}
assert_equal "more text", res
res = XPath::first(doc.root, "b[last()]")
assert_equal '3', res.attributes['id']
res = XPath::first(doc.root, "b[position()=2]")
assert_equal '2', res.attributes['id']
res = XPath::first(doc.root, "*[name()='c']")
assert_equal "c", res.name
end
# Contributed by Mike Stok
def test_starts_with
source = <<-EOF
<foo>
<a href="mailto:a@b.c">a@b.c</a>
<a href="http://www.foo.com">http://www.foo.com</a>
</foo>
EOF
doc = Document.new source
mailtos = doc.elements.to_a("//a[starts-with(@href, 'mailto:')]")
assert_equal 1, mailtos.size
assert_equal "mailto:a@b.c", mailtos[0].attributes['href']
ailtos = doc.elements.to_a("//a[starts-with(@href, 'ailto:')]")
assert_equal 0, ailtos.size
end
def test_string_length
doc = Document.new <<-EOF
<AAA>
<Q/>
<SSSS/>
<BB/>
<CCC/>
<DDDDDDDD/>
<EEEE/>
</AAA>
EOF
assert doc, "create doc"
set = doc.elements.to_a("//*[string-length(name()) = 3]")
assert_equal 2, set.size, "nodes with names length = 3"
set = doc.elements.to_a("//*[string-length(name()) < 3]")
assert_equal 2, set.size, "nodes with names length < 3"
set = doc.elements.to_a("//*[string-length(name()) > 3]")
assert_equal 3, set.size, "nodes with names length > 3"
end
# Test provided by Mike Stok
def test_contains
source = <<-EOF
<foo>
<a href="mailto:a@b.c">a@b.c</a>
<a href="http://www.foo.com">http://www.foo.com</a>
</foo>
EOF
doc = Document.new source
[['o', 2], ['foo', 1], ['bar', 0]].each { |test|
search, expected = test
set = doc.elements.to_a("//a[contains(@href, '#{search}')]")
assert_equal expected, set.size
}
end
# Mike Stok and Sean Russell
def test_substring
# examples from http://www.w3.org/TR/xpath#function-substring
doc = Document.new('<test string="12345" />')
d = Document.new("<a b='1'/>")
#puts XPath.first(d, 'node()[0 + 1]')
#d = Document.new("<a b='1'/>")
#puts XPath.first(d, 'a[0 mod 0]')
[ [1.5, 2.6, '234'],
[0, 3, '12'],
[0, '0 div 0', ''],
[1, '0 div 0', ''],
['-42', '1 div 0', '12345'],
['-1 div 0', '1 div 0', '']
].each { |start, length, expected|
set = doc.elements.to_a("//test[substring(@string, #{start}, #{length}) = '#{expected}']")
assert_equal 1, set.size, "#{start}, #{length}, '#{expected}'"
}
end
def test_substring_angrez
testString = REXML::Functions::substring_after("helloworld","hello")
assert_equal( 'world', testString )
end
def test_translate
source = <<-EOF
<doc>
<case name='w3c one' result='BAr' /> <!-- w3c -->
<case name='w3c two' result='AAA' /> <!-- w3c -->
<case name='alchemy' result="gold" /> <!-- mike -->
<case name='vbxml one' result='A Space Odyssey' />
<case name='vbxml two' result='AbCdEf' />
</doc>
EOF
doc = Document.new(source)
[ ['bar', 'abc', 'ABC', 'w3c one'],
['--aaa--','abc-','ABC', 'w3c two'],
['lead', 'dear language', 'doll groover', 'alchemy'],
['A Space Odissei', 'i', 'y', 'vbxml one'],
['abcdefg', 'aceg', 'ACE', 'vbxml two'],
].each { |arg1, arg2, arg3, name|
translate = "translate('#{arg1}', '#{arg2}', '#{arg3}')"
set = doc.elements.to_a("//case[@result = #{translate}]")
assert_equal 1, set.size, translate
assert_equal name, set[0].attributes['name']
}
end
def test_name
d = REXML::Document.new("<a xmlns:x='foo'><b/><x:b/></a>")
assert_equal 1, d.root.elements.to_a('*[name() = "b"]').size
assert_equal 1, d.elements.to_a('//*[name() = "x:b"]').size
end
def test_local_name
d = REXML::Document.new("<a xmlns:x='foo'><b/><x:b/></a>")
assert_equal 2, d.root.elements.to_a('*[local_name() = "b"]').size
assert_equal 2, d.elements.to_a('//*[local_name() = "b"]').size
end
def test_substring2
doc = Document.new('<test string="12345" />')
assert_equal(1,doc.elements.to_a("//test[substring(@string,2)='2345']").size)
end
# Submitted by Kouhei
def test_floor_ceiling_round
source = "<a><b id='1'/><b id='2'/><b id='3'/></a>"
doc = REXML::Document.new(source)
id_1 = doc.elements["/a/b[@id='1']"]
id_2 = doc.elements["/a/b[@id='2']"]
id_3 = doc.elements["/a/b[@id='3']"]
good = {
"floor" => [[], [id_1], [id_2], [id_3]],
"ceiling" => [[id_1], [id_2], [id_3], []],
"round" => [[id_1], [id_2], [id_3], []]
}
good.each do |key, value|
(0..3).each do |i|
xpath = "//b[number(@id) = #{key}(#{i+0.5})]"
assert_equal(value[i], REXML::XPath.match(doc, xpath))
end
end
good["round"] = [[], [id_1], [id_2], [id_3]]
good.each do |key, value|
(0..3).each do |i|
xpath = "//b[number(@id) = #{key}(#{i+0.4})]"
assert_equal(value[i], REXML::XPath.match(doc, xpath))
end
end
end
# Submitted by Kou
def test_lang
d = Document.new(<<-XML)
<a xml:lang="en">
<b xml:lang="ja">
<c xml:lang="fr"/>
<d/>
<e xml:lang="ja-JP"/>
<f xml:lang="en-US"/>
</b>
</a>
XML
assert_equal(1, d.elements.to_a("//*[lang('fr')]").size)
assert_equal(3, d.elements.to_a("//*[lang('ja')]").size)
assert_equal(2, d.elements.to_a("//*[lang('en')]").size)
assert_equal(1, d.elements.to_a("//*[lang('en-us')]").size)
d = Document.new(<<-XML)
<root>
<para xml:lang="en"/>
<div xml:lang="en"><para/></div>
<para xml:lang="EN"/>
<para xml:lang="en-us"/>
</root>
XML
assert_equal(5, d.elements.to_a("//*[lang('en')]").size)
end
def test_ticket_60
document = REXML::Document.new("<a><b>A</b><b>1</b></a>")
assert_equal( "A", REXML::XPath.first(document, '//b[.="A"]').text )
assert_equal( "1", REXML::XPath.first(document, '//b[.="1"]').text )
end
def test_normalize_space
source = "<a><!--COMMENT A--><b><!-- COMMENT A --></b></a>"
doc = REXML::Document.new(source)
predicate = "string(.)=normalize_space('\nCOMMENT \n A \n\n ')"
m = REXML::XPath.match(doc, "//comment()[#{predicate}]")
assert_equal( [REXML::Comment.new("COMMENT A")], m )
end
end

View file

@ -0,0 +1,32 @@
require 'rexml/document'
require 'test/unit'
require 'rexml/functions'
class TC_Rexml_Functions_Number < Test::Unit::TestCase
def test_functions_number_int
telem = REXML::Element.new("elem")
telem.text="9"
assert_equal(9, REXML::Functions::number(telem))
end
def test_functions_number_float
telem = REXML::Element.new("elem")
telem.text="10.4"
assert_equal(10.4, REXML::Functions::number(telem))
end
def test_functions_number_negative_int
telem = REXML::Element.new("elem")
telem.text="-9"
assert_equal(-9, REXML::Functions::number(telem))
end
def test_functions_number_negative_float
telem = REXML::Element.new("elem")
telem.text="-9.13"
assert_equal(-9.13, REXML::Functions::number(telem))
end
#def test_functions_number_scientific_notation
# telem = REXML::Element.new("elem")
# telem.text="9.13E12"
# assert_equal(9.13E12, REXML::Functions::number(telem))
#end
end

126
test/rexml/test_jaxen.rb Normal file
View file

@ -0,0 +1,126 @@
require "rexml/document"
require "rexml/xpath"
require 'test/unit/testcase'
# Harness to test REXML's capabilities against the test suite from Jaxen
# ryan.a.cox@gmail.com
class JaxenTester < Test::Unit::TestCase
include REXML
def test_axis ; test("axis") ; end
def test_basic ; test("basic") ; end
def test_basicupdate ; test("basicupdate") ; end
def test_contents ; test("contents") ; end
def test_defaultNamespace ; test("defaultNamespace") ; end
def test_fibo ; test("fibo") ; end
def test_id ; test("id") ; end
def test_jaxen24 ; test("jaxen24") ; end
def test_lang ; test("lang") ; end
def test_message ; test("message") ; end
def test_moreover ; test("moreover") ; end
def test_much_ado ; test("much_ado") ; end
def test_namespaces ; test("namespaces") ; end
def test_nitf ; test("nitf") ; end
def test_numbers ; test("numbers") ; end
def test_pi ; test("pi") ; end
def test_pi2 ; test("pi2") ; end
def test_simple ; test("simple") ; end
def test_testNamespaces ; test("testNamespaces") ; end
def test_text ; test("text") ; end
def test_underscore ; test("underscore") ; end
def test_web ; test("web") ; end
def test_web2 ; test("web2") ; end
def test( fname )
xml_dir = "test/data"
# Dir.entries( xml_dir ).each { |fname|
# if fname =~ /\.xml$/
file = File.new( File.join( xml_dir, fname+".xml" ))
doc = Document.new( file )
XPath.each( doc, "/tests/document" ) {|e| handleDocument(e)}
# end
# }
end
private
# processes a tests/document/context node
def handleContext( testDoc, ctxElement)
testCtx = XPath.match( testDoc, ctxElement.attributes["select"] )[0]
namespaces = {}
if testCtx.class == Element
testCtx.prefixes.each { |pre| handleNamespace( testCtx, pre, namespaces ) }
end
variables = {}
XPath.each( ctxElement, "@*[namespace-uri() = 'http://jaxen.org/test-harness/var']") { |attrib| handleVariable(testCtx, variables, attrib) }
XPath.each( ctxElement, "valueOf") { |e| handleValueOf(testCtx, variables, namespaces, e) }
XPath.each( ctxElement, "test[not(@exception) or (@exception != 'true') ]") { |e| handleNominalTest(testCtx,variables, namespaces, e) }
XPath.each( ctxElement, "test[@exception = 'true']") { |e| handleExceptionalTest(testCtx,variables, namespaces, e) }
end
# processes a tests/document/context/valueOf or tests/document/context/test/valueOf node
def handleValueOf(ctx,variables, namespaces, valueOfElement)
expected = valueOfElement.text
got = XPath.match( ctx, valueOfElement.attributes["select"], namespaces, variables )[0]
assert_true( (got.nil? && expected.nil?) || !got.nil? )
case got.class
when Element
assert_equal( got.class, Element )
when Attribute, Text, Comment, TrueClass, FalseClass
assert_equal( expected, got.to_s )
when Instruction
assert_equal( expected, got.content )
when Fixnum
assert_equal( exected.to_f, got )
when String
# normalize values for comparison
got = "" if got == nil or got == ""
expected = "" if expected == nil or expected == ""
assert_equal( expected, got )
else
assert_fail( "Wassup?" )
end
end
# processes a tests/document/context/test node ( where @exception is false or doesn't exist )
def handleNominalTest(ctx, variables, namespaces, testElement)
expected = testElement.attributes["count"]
got = XPath.match( ctx, testElement.attributes["select"], namespaces, variables )
# might be a test with no count attribute, but nested valueOf elements
assert( expected == got.size.to_s ) if !expected.nil?
XPath.each( testElement, "valueOf") { |e|
handleValueOf(got, variables, namespaces, e)
}
end
# processes a tests/document/context/test node ( where @exception is true )
def handleExceptionalTest(ctx, variables, namespaces, testElement)
assert_raise( Exception ) {
XPath.match( ctx, testElement.attributes["select"], namespaces, variables )
}
end
# processes a tests/document node
def handleDocument(docElement)
puts "- Processing document: #{docElement.attributes['url']}"
testFile = File.new( docElement.attributes["url"] )
testDoc = Document.new testFile
XPath.each( docElement, "context") { |e| handleContext(testDoc, e) }
end
# processes a variable definition in a namespace like <test var:foo="bar">
def handleVariable( ctx, variables, attrib )
puts "--- Found attribute: #{attrib.name}"
variables[attrib.name] = attrib.value
end
# processes a namespace definition like <test xmlns:foo="fiz:bang:bam">
def handleNamespace( ctx, prefix, namespaces )
puts "--- Found namespace: #{prefix}"
namespaces[prefix] = ctx.namespaces[prefix]
end
end

101
test/rexml/test_light.rb Normal file
View file

@ -0,0 +1,101 @@
require "test/unit/testcase"
require "rexml/light/node"
require "rexml/parsers/lightparser"
include REXML::Light
class LightTester < Test::Unit::TestCase
def test_parse_large
parser = REXML::Parsers::LightParser.new( File.new( "test/data/documentation.xml" ) )
root = parser.parse
end
# FIXME INCOMPLETE
# This is because the light API is not yet ready to be used to produce
# trees.
=begin
def test_add_element
doc = Node.new
foo = doc.add_element( 'foo' )
assert_equal( "foo", foo.name )
end
def test_add_attribute
foo = Node.new( "a" )
foo["attr"] = "bar"
assert_equal( "bar", foo["attr"] )
end
def test_write_document
r = make_small_document
assert_equal( "<a><b/><c/></a>", r.to_s )
end
def test_add_attribute_under_namespace
foo = Node.new("a")
foo["attr", "a"] = "1"
foo["attr", "b"] = "2"
foo["attr"] = "3"
assert_equal( '1', foo['attr', 'a'] )
assert_equal( '2', foo['attr', 'b'] )
assert_equal( '3', foo['attr'] )
end
def test_change_namespace_of_element
foo = Node.new
assert_equal( '', foo.namespace )
foo.namespace = 'a'
assert_equal( 'a', foo.namespace )
end
def test_access_child_elements
foo = make_small_document
assert_equal( 1, foo.size )
a = foo[0]
assert_equal( 2, a.size )
assert_equal( 'b', a[0].name )
assert_equal( 'c', a[1].name )
end
def test_itterate_over_children
foo = make_small_document
ctr = 0
foo[0].each { ctr += 1 }
assert_equal( 2, ctr )
end
def test_add_text
foo = Node.new( "a" )
foo.add_text( "Sean" )
sean = foo[0]
assert( sean.node_type == :text )
end
def test_add_instruction
foo = Node.new( "a" )
foo.add_instruction( "target", "value" )
assert( foo[0].node_type == :processing_instruction )
end
def test_add_comment
foo = Node.new( "a" )
foo.add_comment( "target", "value" )
assert( foo[0].node_type == :comment )
end
def test_get_root
foo = Node.new( 'a' )
10.times { foo = foo.add_element('b') }
assert_equals( 'b', foo.name )
assert_equals( 'a', foo.root.name )
end
def make_small_document
r = Node.new
a = r.add_element( "a" )
a.add_element( 'b' )
a.add_element( 'c' )
r
end
=end
end

View file

@ -0,0 +1,11 @@
require 'test/unit/testcase'
require 'rexml/parsers/lightparser'
class LightParserTester < Test::Unit::TestCase
include REXML
def test_parsing
f = File.new( "test/data/documentation.xml" )
parser = REXML::Parsers::LightParser.new( f )
root = parser.parse
end
end

207
test/rexml/test_listener.rb Normal file
View file

@ -0,0 +1,207 @@
# coding: binary
require 'test/unit/testcase'
require 'rexml/document'
require 'rexml/streamlistener'
class BaseTester < Test::Unit::TestCase
def test_empty
return unless defined? @listener
# Empty.
t1 = %Q{<string></string>}
assert_equal( "", @listener.parse( t1 ),
"Empty" )
end
def test_space
return unless defined? @listener
# Space.
t2 = %Q{<string> </string>}
assert_equal( " ", @listener.parse( t2 ),
"Space" )
end
def test_whitespace
return unless defined? @listener
# Whitespaces.
t3 = %Q{<string>RE\n \t \n \t XML</string>}
assert_equal( "RE\n \t \n \t XML", @listener.parse( t3 ),
"Whitespaces" )
end
def test_leading_trailing_whitespace
return unless defined? @listener
# Leading and trailing whitespaces.
t4 = %Q{<string> REXML </string>}
assert_equal( " REXML ", @listener.parse( t4 ),
"Leading and trailing whitespaces" )
end
def test_entity_reference
return unless defined? @listener
# Entity reference.
t5 = %Q{<string>&lt;&gt;&amp;lt;&amp;gt;</string>}
assert_equal( "<>&lt;&gt;", @listener.parse( t5 ),
"Entity reference" )
end
def test_character_reference
return unless defined? @listener
# Character reference.
t6 = %Q{<string>&#xd;</string>}
assert_equal( "\r", @listener.parse( t6 ),
"Character reference." )
end
def test_cr
return unless defined? @listener
# CR.
t7 = %Q{<string> \r\n \r \n </string>}
assert_equal( " \n \n \n ".unpack("C*").inspect,
@listener.parse( t7 ).unpack("C*").inspect, "CR" )
end
# The accent bug, and the code that exibits the bug, was contributed by
# Guilhem Vellut
class AccentListener
def tag_start(name,attributes)
#p name
#p attributes
end
def tag_end(name)
#p "/"+name
end
def xmldecl(a,b,c)
#puts "#{a} #{b} #{c}"
end
def text(tx)
#p tx
end
end
def test_accents
source = '<?xml version="1.0" encoding="ISO-8859-1"?>
<g>
<f a="é" />
</g>'
doc = REXML::Document.new( source )
a = doc.elements['/g/f'].attribute('a')
if a.value.respond_to? :force_encoding
a.value.force_encoding('binary')
end
assert_equal( 'é', a.value)
doc = REXML::Document.parse_stream(
File::new("test/data/stream_accents.xml"),
AccentListener::new
)
end
end
#########################################################
# Other parsers commented out because they cause failures
# in the unit tests, which aren't REXMLs problems
# #######################################################
=begin
begin
require 'xmlparser'
class MyXMLParser
class Listener < XML::Parser
# Dummy handler to get XML::Parser::XML_DECL event.
def xmlDecl; end
end
def parse( stringOrReadable )
text = ""
Listener.new.parse( stringOrReadable ) do | type, name, data |
case type
when XML::Parser::CDATA
text << data
end
end
text
end
end
class XMLParserTester < BaseTester
def setup
@listener = MyXMLParser.new
end
end
rescue LoadError
#puts "XMLParser not available"
end
begin
require 'nqxml/tokenizer'
class MyNQXMLLightWeightListener
def parse( stringOrReadable )
text = ""
isText = false
tokenizer = NQXML::Tokenizer.new( stringOrReadable )
tokenizer.each do | entity |
case entity
when NQXML::Tag
if !entity.isTagEnd
isText = true
else
isText = false
end
when NQXML::Text
if isText
text << entity.text
isText = false
end
end
end
text
end
end
class NQXMLTester < BaseTester
def setup
@listener = MyNQXMLLightWeightListener.new
end
end
rescue LoadError
#puts "NQXML not available"
end
=end
class MyREXMLListener
include REXML::StreamListener
def initialize
@text = nil
end
def parse( stringOrReadable )
@text = ""
REXML::Document.parse_stream( stringOrReadable, self )
@text
end
def text( text )
@text << text
end
end
class REXMLTester < BaseTester
def setup
@listener = MyREXMLListener.new
end
def test_character_reference_2
t6 = %Q{<string>&#xd;</string>}
assert_equal( t6.strip, REXML::Document.new(t6).to_s )
end
end
if __FILE__ == $0
case ARGV[0]
when 'NQXML'
RUNIT::CUI::TestRunner.run( NQXMLTester.suite )
when 'XMLParser'
RUNIT::CUI::TestRunner.run( XMLParserTester.suite )
else
RUNIT::CUI::TestRunner.run( REXMLTester.suite )
end
end

View file

@ -0,0 +1,38 @@
require 'test/unit'
require 'rexml/document'
class OrderTester < Test::Unit::TestCase
def initialize n
@doc = REXML::Document.new(DOC)
@figs = REXML::XPath.match(@doc,'//figure')
@names = @figs.collect {|f| f.attributes['src']}
super
end
def test_fig1
assert_equal 'fig1', @figs[0].attributes['src']
end
def test_fig2
assert_equal 'fig2', @figs[1].attributes['src']
end
def test_fig3
assert_equal 'fig3', @figs[2].attributes['src']
end
def test_fig4
assert_equal 'fig4', @figs[3].attributes['src']
end
end
DOC = <<END
<paper>
<title>Remove this element and figs order differently</title>
<figure src="fig1"/>
<figure src="fig2"/>
<p>Para of text</p>
<p>Remove this and figs order differently</p>
<section>
<figure src="fig3"/>
</section>
<figure src="fig4"/>
</paper>
END

View file

@ -0,0 +1,58 @@
#! /usr/local/bin/ruby
require 'test/unit'
require 'rexml/document'
class TestNotationDeclMixin < Test::Unit::TestCase
def setup
@pubid1 = "TEST1"
@pubid2 = "TEST2"
@sysid2 = "urn:x-henrikmartensson.org:test2"
@pubid3 = "TEST3"
@pubid4 = "TEST4"
@sysid4 = "urn:x-henrikmartensson.org:test4"
@pubid5 = "TEST5"
@sysid5 = "urn:x-henrikmartensson.org:test5"
@pubid6 = "TEST6"
@sysid6 = "urn:x-henrikmartensson.org:test6"
@sysid7 = "urn:x-henrikmartensson.org:test7"
doc_string = <<-"XMLEND"
<!DOCTYPE r SYSTEM "urn:x-henrikmartensson:test" [
<!NOTATION n1 PUBLIC "#{@pubid1}">
<!NOTATION n2 PUBLIC "#{@pubid2}" "#{@sysid2}">
<!NOTATION n3 PUBLIC '#{@pubid3}'>
<!NOTATION n4 PUBLIC '#{@pubid4}' '#{@sysid4}'>
<!NOTATION n5 PUBLIC "#{@pubid5}" '#{@sysid5}'>
<!NOTATION n6 PUBLIC '#{@pubid6}' "#{@sysid6}">
<!NOTATION n7 SYSTEM "#{@sysid7}">
]>
<r/>
XMLEND
@doctype = REXML::Document.new(doc_string).doctype
end
def test_name
assert_equal('n1', @doctype.notation('n1').name)
end
def test_public_2
assert_equal(@pubid1, @doctype.notation('n1').public)
assert_equal(@pubid2, @doctype.notation('n2').public)
assert_equal(@pubid3, @doctype.notation('n3').public)
assert_equal(@pubid4, @doctype.notation('n4').public)
assert_equal(@pubid5, @doctype.notation('n5').public)
assert_equal(@pubid6, @doctype.notation('n6').public)
assert_nil(@doctype.notation('n7').public)
end
def test_system_2
assert_equal(@sysid2, @doctype.notation('n2').system)
assert_nil(@doctype.notation('n3').system)
assert_equal(@sysid4, @doctype.notation('n4').system)
assert_equal(@sysid5, @doctype.notation('n5').system)
assert_equal(@sysid6, @doctype.notation('n6').system)
assert_equal(@sysid7, @doctype.notation('n7').system)
end
end

View file

@ -0,0 +1,23 @@
#! /usr/bin/ruby
require 'test/unit'
require 'rexml/document'
class TestNotationDecl < Test::Unit::TestCase
def setup
doc_string = <<-'XMLEND'
<!DOCTYPE r SYSTEM "urn:x-henrikmartensson:test" [
<!NOTATION n1 PUBLIC "-//HM//NOTATION TEST1//EN" 'urn:x-henrikmartensson.org:test5'>
<!NOTATION n2 PUBLIC '-//HM//NOTATION TEST2//EN' "urn:x-henrikmartensson.org:test6">
]>
<r/>
XMLEND
@doctype = REXML::Document.new(doc_string).doctype
end
def test_notation
assert(@doctype.notation('n1'), "Testing notation n1")
assert(@doctype.notation('n2'), "Testing notation n2")
end
end

101
test/rexml/test_order.rb Normal file
View file

@ -0,0 +1,101 @@
require 'test/unit'
require 'rexml/document'
require 'zlib'
class OrderTester < Test::Unit::TestCase
def setup
@doc = REXML::Document.new(TESTDOC)
@items = REXML::XPath.match(@doc,'//x')
end
def test_first_element
assert_equal '1', @items[0].attributes['id']
end
def test_second_element
assert_equal '2', @items[1].attributes['id']
end
def test_third_element
assert_equal '3', @items[2].attributes['id']
end
def test_order
d = REXML::Document.new( "<a><x id='1'/><x id='2'/><x id='3'/>
<x id='4'/><x id='5'/></a>" )
items = REXML::XPath.match( d, '//x' )
assert_equal( %w{1 2 3 4 5}, items.collect{|e| e.attributes['id']} )
d = REXML::Document.new( "<a>
<x><z><y id='1'/><y id='2'/></z><y id='3'/></x>
<x><y id='4'/></x></a>" )
items = REXML::XPath.match( d, '//y' )
assert_equal( %w{1 2 3 4}, items.collect{|e| e.attributes['id']} )
end
# Provided by Tom Talbott
def test_more_ordering
doc = REXML::Document.new( Zlib::GzipReader.new( File.new( 'test/data/LostineRiver.kml.gz' ) ) )
actual = [
"Head south from Phinney Ave N",
"Turn left at N 36th St",
"Turn right at Fremont Ave N",
"Continue on 4th Ave N",
"Turn left at Westlake Ave N",
"Bear right at 9th Ave N",
"Turn left at Mercer St",
"Take the I-5 ramp",
"Take the I-5 S ramp",
"Take the I-90 E exit #164 to Bellevue/Spokane/4th Ave S.",
"Take the I-90 E ramp to Bellevue/Spokane",
"Take exit #137 to Wanapum Dam/Richland",
"Bear right at WA-26",
"Bear right and head toward WA-243",
"Continue on WA-243",
"Bear right at WA-24",
"Continue on WA-240",
"Turn right at WA-240 E",
"Take the I-182 W ramp to Yakima (I-82)/Pendleton",
"Take the I-82 E ramp to Umatilla/Pendleton",
"Take the I-84 E ramp to Pendleton",
"Take the OR-82 exit #261 to La Grande/Elgin",
"Turn right at Island Ave",
"Continue on W 1st St",
"Turn left at N McAlister Rd",
"Bear right at OR-82",
"Continue on Wallowa Lake Hwy",
"Continue on OR-82",
"Continue on Ruckman Ave",
"Continue on OR-82",
"Continue on S 8th Ave",
"Turn right at Albany St",
"Continue on OR-82",
"Continue on Wallowa Lake Hwy",
"Continue on N Madison St",
"Bear left at W 1st St",
"Continue on Wallowa Lake Hwy",
"Continue on Water St",
"Bear right at Lostine River Rd",
"Bear right and head toward Lostine River Rd",
"Turn right at Lostine River Rd",
"Continue on NF-8210",
"Turn right and head toward NF-8210",
"Turn right at NF-8210",
"",
"Route"
]
count = 0
REXML::XPath.each( doc, "//Placemark") { |element|
n = element.elements["name"].text.squeeze(" ")
assert_equal( actual[count], n ) unless n =~ /Arrive at/
count += 1
}
end
end
TESTDOC = <<END
<a>
<b/>
<x id='1'/>
<c/>
<d>
<x id='2'/>
</d>
<x id='3'/>
</a>
END

View file

@ -0,0 +1,40 @@
# ISSUE 32
require 'test/unit'
require 'rexml/document'
p [REXML::VERSION, RUBY_VERSION, RUBY_RELEASE_DATE]
# daz - for report by Dan Kohn in:
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/156328
class XPathTesterDd < Test::Unit::TestCase
include REXML
def setup
@@docDd = Document.new(<<-EOS, :ignore_whitespace_nodes => :all)
<a>
<b x='ab01A'>
<c y='abc01A'>Success</c>
</b>
<b x='ab02A' y='ab02B'>
<c>abc02C</c>
</b>
</a>
EOS
end
def test_Dd_preceding_sibling_children
arr = []
XPath.each(@@docDd, "//b[@x='ab02A']/preceding-sibling::b/child::*") do |cell|
arr << cell.texts.join
end
assert_equal( 'Success', arr.join )
end
def test_Dd_preceding_sibling_all
arr = []
XPath.each(@@docDd, "//b[@x='ab02A']/preceding-sibling::*") do |cell|
arr << cell.to_s
end
assert_equal( "<b x='ab01A'><c y='abc01A'>Success</c></b>", arr.join )
end
end

View file

@ -0,0 +1,100 @@
require "test/unit/testcase"
require 'rexml/parsers/pullparser'
class PullParserTester < Test::Unit::TestCase
include REXML
def test_basics
source = '<?xml version="1.0"?>
<!DOCTYPE blah>
<a>foo &lt;<b attribute="value">bar</b> nooo</a>'
parser = REXML::Parsers::PullParser.new(source)
res = { :text=>0 }
until parser.empty?
results = parser.pull
res[ :xmldecl ] = true if results.xmldecl?
res[ :doctype ] = true if results.doctype?
res[ :a ] = true if results.start_element? and results[0] == 'a'
if results.start_element? and results[0] == 'b'
res[ :b ] = true
assert_equal 'value', results[1]['attribute']
end
res[ :text ] += 1 if results.text?
end
[ :xmldecl, :doctype, :a, :b ].each { |tag|
assert res[tag] , "#{tag} wasn't processed"
}
assert_equal 4, res[ :text ]
rescue ParseException
puts $!
end
def test_bad_document
source = "<a><b></a>"
parser = REXML::Parsers::PullParser.new(source)
assert_raise(ParseException, "Parsing should have failed") {
results = parser.pull while parser.has_next?
}
end
def test_entity_replacement
source = '<!DOCTYPE foo [
<!ENTITY la "1234">
<!ENTITY lala "--&la;--">
<!ENTITY lalal "&la;&la;">
]><a><la>&la;</la><lala>&lala;</lala></a>'
pp = REXML::Parsers::PullParser.new( source )
el_name = ''
while pp.has_next?
event = pp.pull
case event.event_type
when :start_element
el_name = event[0]
when :text
case el_name
when 'la'
assert_equal('1234', event[1])
when 'lala'
assert_equal('--1234--', event[1])
end
end
end
end
def test_peek_unshift
source = "<a><b/></a>"
pp = REXML::Parsers::PullParser.new(source)
# FINISH ME!
end
def test_inspect
xml = '<a id="1"><b id="2">Hey</b></a>'
parser = Parsers::PullParser.new( xml )
while parser.has_next?
pull_event = parser.pull
if pull_event.start_element?
peek = parser.peek()
peek.inspect
end
end
end
def test_peek
xml = '<a id="1"><b id="2">Hey</b></a>'
parser = Parsers::PullParser.new( xml )
names = %w{ a b }
while parser.has_next?
pull_event = parser.pull
if pull_event.start_element?
assert_equal( :start_element, pull_event.event_type )
assert_equal( names.shift, pull_event[0] )
if names[0] == 'b'
peek = parser.peek()
assert_equal( :start_element, peek.event_type )
assert_equal( names[0], peek[0] )
end
end
end
assert_equal( 0, names.length )
end
end

View file

@ -0,0 +1,15 @@
#!/sw/bin/ruby
require 'test/unit'
require 'rexml/document'
class TestIssuezillaParsing < Test::Unit::TestCase
def test_rexml
doc = REXML::Document.new(File.new("test/data/ofbiz-issues-full-177.xml"))
ctr = 1
doc.root.each_element('//issue') do |issue|
assert_equal( ctr, issue.elements['issue_id'].text.to_i )
ctr += 1
end
end
end

286
test/rexml/test_sax.rb Normal file
View file

@ -0,0 +1,286 @@
require "test/unit/testcase"
require 'rexml/sax2listener'
require 'rexml/parsers/sax2parser'
class SAX2Tester < Test::Unit::TestCase
include REXML
def test_characters
d = Document.new( "<A>@blah@</A>" )
txt = d.root.text
p = Parsers::SAX2Parser.new "<A>@blah@</A>"
p.listen(:characters) {|x| assert_equal txt, x}
p.listen(:characters, ["A"]) {|x| assert_equal txt,x}
p.parse
end
def test_entity_replacement
source = '<!DOCTYPE foo [
<!ENTITY la "1234">
<!ENTITY lala "--&la;--">
<!ENTITY lalal "&la;&la;">
]><a><la>&la;</la><lala>&lala;</lala></a>'
sax = Parsers::SAX2Parser.new( source )
results = []
sax.listen(:characters) {|x| results << x }
sax.parse
assert_equal 2, results.size
assert_equal '1234', results[0]
assert_equal '--1234--', results[1]
end
def test_sax2
f = File.new("test/data/documentation.xml")
parser = Parsers::SAX2Parser.new( f )
# Listen to all events on the following elements
count = 0
blok = proc { |uri,localname,qname,attributes|
assert %w{ bugs todo }.include?(localname),
"Mismatched name; we got '#{qname}'\nArgs were:\n\tURI: #{uri}\n\tLOCALNAME: #{localname}\n\tQNAME: #{qname}\n\tATTRIBUTES: #{attributes.inspect}\n\tSELF=#{blok}"
count += 1
}
start_document = 0
end_document = 0
parser.listen( :start_document ) { start_document += 1 }
parser.listen( :end_document ) { end_document += 1 }
parser.listen( :start_element, %w{ changelog bugs todo }, &blok )
# Listen to all events on the following elements. Synonymous with
# listen( :start_element, %w{ ... } )
parser.listen( %w{ changelog bugs todo }, &blok )
# Listen for all start element events
parser.listen( :start_element ) { |uri,localname,qname,attributes|
}
listener = MySAX2Listener.new
# Listen for all events
parser.listen( listener )
# Listen for all events on the given elements. Does not include children
# events. Regular expressions work as well!
parser.listen( %w{ /change/ bugs todo }, listener )
# Test the deafening method
blok = proc { |uri,localname,qname,attributes|
assert_fail "This listener should have been deafened!"
}
parser.listen( %w{ changelog }, &blok )
parser.deafen( &blok )
tc = 0
parser.listen( :characters, %w{version} ) {|text|
assert(text=~/@ANT_VERSION@/, "version was '#{text}'")
tc += 1
}
begin
parser.parse
rescue => exception
if exception.kind_of? Test::Unit::AssertionFailedError
raise exception
end
puts $!
puts exception.backtrace
end
assert_equal 2, count
assert_equal 1, tc
assert_equal 1, start_document
assert_equal 1, end_document
end
# used by test_simple_doctype_listener
# submitted by Jeff Barczewski
class SimpleDoctypeListener
include REXML::SAX2Listener
attr_reader :name, :pub_sys, :long_name, :uri
def initialize
@name = @pub_sys = @long_name = @uri = nil
end
def doctype(name, pub_sys, long_name, uri)
@name = name
@pub_sys = pub_sys
@long_name = long_name
@uri = uri
end
end
# test simple non-entity doctype in sax listener
# submitted by Jeff Barczewski
def test_simple_doctype_listener
xml = <<-END
<?xml version="1.0"?>
<!DOCTYPE greeting PUBLIC "Hello Greeting DTD" "http://foo/hello.dtd">
<greeting>Hello, world!</greeting>
END
parser = Parsers::SAX2Parser.new(xml)
dtl = SimpleDoctypeListener.new
parser.listen(dtl)
tname = nil
tpub_sys = nil
tlong_name = nil
turi = nil
parser.listen(:doctype) do |name, pub_sys, long_name, uri|
tname = name
tpub_sys = pub_sys
tlong_name = long_name
turi = uri
end
parser.parse
assert_equal 'greeting', tname, 'simple doctype block listener failed - incorrect name'
assert_equal 'PUBLIC', tpub_sys, 'simple doctype block listener failed - incorrect pub_sys'
assert_equal 'Hello Greeting DTD', tlong_name, 'simple doctype block listener failed - incorrect long_name'
assert_equal 'http://foo/hello.dtd', turi, 'simple doctype block listener failed - incorrect uri'
assert_equal 'greeting', dtl.name, 'simple doctype listener failed - incorrect name'
assert_equal 'PUBLIC', dtl.pub_sys, 'simple doctype listener failed - incorrect pub_sys'
assert_equal 'Hello Greeting DTD', dtl.long_name, 'simple doctype listener failed - incorrect long_name'
assert_equal 'http://foo/hello.dtd', dtl.uri, 'simple doctype listener failed - incorrect uri'
end
# test doctype with missing name, should throw ParseException
# submitted by Jeff Barczewseki
def test_doctype_with_mising_name_throws_exception
xml = <<-END
<?xml version="1.0"?>
<!DOCTYPE >
<greeting>Hello, world!</greeting>
END
parser = Parsers::SAX2Parser.new(xml)
assert_raise(REXML::ParseException, 'doctype missing name did not throw ParseException') do
parser.parse
end
end
class KouListener
include REXML::SAX2Listener
attr_accessor :sdoc, :edoc
attr_reader :selem, :decl, :pi
def initialize
@sdoc = @edoc = @selem = false
@decl = 0
@pi = 0
end
def start_document
@sdoc = true
end
def end_document
@edoc = true
end
def xmldecl( *arg )
@decl += 1
end
def processing_instruction( *arg )
@pi += 1
end
def start_element( *arg )
@selem = true
end
end
# Submitted by Kou
def test_begin_end_document
parser = Parsers::SAX2Parser.new("<a/>")
kl = KouListener.new
parser.listen(kl)
sd = false
ed = false
parser.listen(:start_document) { sd = true }
parser.listen(:end_document) { ed = true }
parser.parse
assert( sd, ':start_document block failed' )
assert( ed, ':end_document block failed' )
assert( kl.sdoc, ':start_document listener failed' )
assert( kl.edoc, ':end_document listener failed' )
end
# Submitted by Kou
def test_listen_before_start
# FIXME: the following comment should be a test for validity. (The xml declaration
# is invalid).
#parser = Parsers::SAX2Parser.new( "<?xml ?><?pi?><a><?pi?></a>")
parser = Parsers::SAX2Parser.new( "<?xml version='1.0'?><?pi?><a><?pi?></a>")
k1 = KouListener.new
parser.listen( k1 )
xmldecl = false
pi = 0
parser.listen( :xmldecl ) { xmldecl = true }
parser.listen( :processing_instruction ) { pi += 1 }
parser.parse
assert( xmldecl, ':xmldecl failed' )
assert_equal( 2, pi, ':processing_instruction failed' )
assert( k1.decl, 'Listener for xmldecl failed' )
assert_equal( 2, k1.pi, 'Listener for processing instruction failed' )
end
def test_socket
require 'socket'
$port = 12345
Thread.new{
server = TCPServer.new('127.0.0.1', $port)
while (session = server.accept)
session << '<foo>'
Thread.stop
end
}
sleep 1 #to be sure that server is running
@socket = TCPSocket.new('127.0.0.1',$port)
ok = false
test = Thread.new{
parser = REXML::Parsers::SAX2Parser.new @socket
parser.listen( :start_element ) {
ok = true
}
parser.parse
Thread.stop
}
sleep 1 #to be sure that server is running
assert(ok)
end
def test_char_ref_sax2()
parser = REXML::Parsers::SAX2Parser.new('<ABC>&#252;</ABC>')
result = nil
parser.listen(:characters) {|text| result = text.unpack('U*')}
parser.parse()
assert_equal(1, result.size)
assert_equal(252, result[0])
end
def test_char_ref_dom()
doc = REXML::Document.new('<ABC>&#252;</ABC>')
result = doc.root.text.unpack('U*')
assert_equal(1, result.size)
assert_equal(252, result[0])
end
class Ticket68
include REXML::SAX2Listener
end
def test_ticket_68
parser = REXML::Parsers::SAX2Parser.new( File.new('test/data/ticket_68.xml') )
parser.listen( Ticket68.new )
begin
parser.parse
rescue
p parser.source.position
p parser.source.current_line
puts $!.backtrace.join("\n")
flunk $!.message
end
end
end
class MySAX2Listener
include REXML::SAX2Listener
end

104
test/rexml/test_stream.rb Normal file
View file

@ -0,0 +1,104 @@
require "test/unit/testcase"
require "rexml/document"
require 'rexml/streamlistener'
require 'stringio'
class MyListener
include REXML::StreamListener
end
class StreamTester < Test::Unit::TestCase
# Submitted by Han Holl
def test_listener
data = %Q{<session1 user="han" password="rootWeiler" />\n<session2 user="han" password="rootWeiler" />}
b = RequestReader.new( data )
b = RequestReader.new( data )
end
def test_ticket_49
source = StringIO.new( <<-EOL )
<!DOCTYPE foo [
<!ENTITY ent "replace">
]>
<a>&ent;</a>
EOL
REXML::Document.parse_stream(source, MyListener.new)
end
def test_ticket_10
source = StringIO.new( <<-EOL )
<!DOCTYPE foo [
<!ENTITY ent "replace">
<!ATTLIST a
xmlns:human CDATA #FIXED "http://www.foo.com/human">
<!ELEMENT bar (#PCDATA)>
<!NOTATION n1 PUBLIC "-//HM//NOTATION TEST1//EN" 'urn:x-henrikmartensson.org:test5'>
]>
<a/>
EOL
listener = MyListener.new
class << listener
attr_accessor :events
def entitydecl( content )
@events[ :entitydecl ] = true
end
def attlistdecl( element_name, attributes, raw_content )
@events[ :attlistdecl ] = true
end
def elementdecl( content )
@events[ :elementdecl ] = true
end
def notationdecl( content )
@events[ :notationdecl ] = true
end
end
listener.events = {}
REXML::Document.parse_stream( source, listener )
assert( listener.events[:entitydecl] )
assert( listener.events[:attlistdecl] )
assert( listener.events[:elementdecl] )
assert( listener.events[:notationdecl] )
end
end
# For test_listener
class RequestReader
attr_reader :doc
def initialize(io)
@stack = []
@doc = nil
catch(:fini) do
REXML::Document.parse_stream(io, self)
raise IOError
end
end
def tag_start(name, args)
if @doc
@stack.push(REXML::Element.new(name, @stack.last))
else
@doc = REXML::Document.new("<#{name}/>")
@stack.push(@doc.root)
end
args.each do |attr,val|
@stack.last.add_attribute(attr, val)
end
end
def tag_end(name, *args)
@stack.pop
throw(:fini) if @stack.empty?
end
def text(str)
@stack.last.text = str
end
def comment(str)
end
def doctype( name, pub_sys, long_name, uri )
end
def doctype_end
end
end

View file

@ -0,0 +1,56 @@
#------------------------------------------------------------------------------
# file: rexml_test.rb
# desc: test's REXML's XML/XPath implementation
# auth: Philip J Grabner <grabner>at<uberdev>dot<org>
# date: 2006/08/17
# copy: (C) CopyLoose 2006 Bib Development Team <bib-devel>at<uberdev>dot<org>
#------------------------------------------------------------------------------
require 'test/unit'
require 'rexml/document'
class Ticket80 < Test::Unit::TestCase
@@xmlstr = '<?xml version="1.0"?>
<root xmlns="urn:some-xml-ns" xmlns:other="urn:some-other-xml-ns">
<l1-foo>
<l2 value="foo-01"/>
<l2 value="foo-02"/>
<l2 value="foo-03"/>
</l1-foo>
<other:l1>
<l2 value="no-show"/>
</other:l1>
<l1-bar>
<l2 value="bar-01"/>
<l2 value="bar-02"/>
</l1-bar>
</root>'
#----------------------------------------------------------------------------
def test_xpathNamespacedChildWildcard
# tests the "prefix:*" node test syntax
out = Array.new
REXML::XPath.each( REXML::Document.new(@@xmlstr),
'/ns:root/ns:*/ns:l2/@value',
{ 'ns' => 'urn:some-xml-ns' } ) do |node| out.push node.value ; end
chk = [ 'foo-01', 'foo-02', 'foo-03', 'bar-01', 'bar-02' ]
assert_equal chk, out
end
#----------------------------------------------------------------------------
def test_xpathNamespacedChildWildcardWorkaround
# tests a workaround for the "prefix:*" node test syntax
out = Array.new
REXML::XPath.each( REXML::Document.new(@@xmlstr),
'/ns:root/*[namespace-uri()="urn:some-xml-ns"]/ns:l2/@value',
{ 'ns' => 'urn:some-xml-ns' } ) do |node| out.push node.value ; end
chk = [ 'foo-01', 'foo-02', 'foo-03', 'bar-01', 'bar-02' ]
assert_equal chk, out
end
end
#------------------------------------------------------------------------------
# end of rexml_test.rb
#------------------------------------------------------------------------------

View file

@ -0,0 +1,790 @@
require "test/unit/testcase"
require "rexml/document"
require "rexml/validation/relaxng"
class RNGValidation < Test::Unit::TestCase
include REXML
def test_validate
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<element name="C">
<attribute name="X"/>
<zeroOrMore>
<element name="E">
<empty/>
</element>
</zeroOrMore>
</element>
<element name="D">
<empty/>
</element>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
no_error( validator, %q{<A><B><C X="x"><E/><E/></C><D/></B></A>} )
error( validator, %q{<A><B><D/><C X="x"/></B></A>} )
end
def test_sequence
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<element name="C">
<empty/>
</element>
<element name="D">
<empty/>
</element>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B><C/><C/><D/></B></A>} )
error( validator, %q{<A><B><D/><C/></B></A>} )
error( validator, %q{<A><C/><D/></A>} )
no_error( validator, %q{<A><B><C/><D/></B></A>} )
end
def test_choice
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<choice>
<element name="C">
<empty/>
</element>
<element name="D">
<empty/>
</element>
</choice>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B><C/><D/></B></A>} )
no_error( validator, %q{<A><B><D/></B></A>} )
no_error( validator, %q{<A><B><C/></B></A>} )
end
def test_optional
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<optional>
<element name="C">
<empty/>
</element>
</optional>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
no_error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><B><C/></B></A>} )
error( validator, %q{<A><B><D/></B></A>} )
error( validator, %q{<A><B><C/><C/></B></A>} )
end
def test_zero_or_more
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<zeroOrMore>
<element name="C">
<empty/>
</element>
</zeroOrMore>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
no_error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><B><C/></B></A>} )
no_error( validator, %q{<A><B><C/><C/><C/></B></A>} )
error( validator, %q{<A><B><D/></B></A>} )
error( validator, %q{<A></A>} )
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<zeroOrMore>
<element name="C">
<empty/>
</element>
<element name="D">
<empty/>
</element>
</zeroOrMore>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
no_error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><B><C/><D/></B></A>} )
no_error( validator, %q{<A><B><C/><D/><C/><D/></B></A>} )
error( validator, %q{<A><B><D/></B></A>} )
end
def test_one_or_more
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<oneOrMore>
<element name="C">
<empty/>
</element>
</oneOrMore>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><B><C/></B></A>} )
no_error( validator, %q{<A><B><C/><C/><C/></B></A>} )
error( validator, %q{<A><B><D/></B></A>} )
error( validator, %q{<A></A>} )
end
def test_attribute
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<attribute name="X"/>
<attribute name="Y"/>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
error( validator, %q{<A/>} )
error( validator, %q{<A X=""/>} )
no_error( validator, %q{<A X="1" Y="1"/>} )
end
def test_choice_attributes
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<choice>
<attribute name="X"/>
<attribute name="Y"/>
</choice>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A X="1" Y="1"/>} )
error( validator, %q{<A/>} )
no_error( validator, %q{<A X="1"/>})
no_error( validator, %q{<A Y="1"/>} )
end
def test_choice_attribute_element
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<choice>
<attribute name="X"/>
<element name="B"/>
</choice>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A X="1"><B/></A>} )
error( validator, %q{<A/>} )
no_error( validator, %q{<A X="1"/>})
no_error( validator, %q{<A><B/></A>} )
end
def test_empty
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<empty/>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
error( validator, %q{<A>Text</A>} )
no_error( validator, %q{<A/>})
end
def test_text_val
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<text/>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A>Text</A>} )
error( validator, %q{<A/>})
end
def test_choice_text
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<choice>
<element name="B"/>
<text/>
</choice>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/>Text</A>} )
error( validator, %q{<A>Text<B/></A>} )
no_error( validator, %q{<A>Text</A>} )
no_error( validator, %q{<A><B/></A>} )
end
def test_group
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<choice>
<element name="B"/>
<group>
<element name="C"/>
<element name="D"/>
</group>
</choice>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/><C/></A>} )
error( validator, %q{<A><C/></A>} )
no_error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><C/><D/></A>} )
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B"/>
<group>
<element name="C"/>
<element name="D"/>
</group>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/><C/></A>} )
error( validator, %q{<A><B/><D/></A>} )
error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><B/><C/><D/></A>} )
end
def test_value
# Values as text nodes
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<value>VaLuE</value>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B>X</B></A>} )
error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><B>VaLuE</B></A>} )
# Values as text nodes, via choice
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<choice>
<value>Option 1</value>
<value>Option 2</value>
</choice>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
error( validator, %q{<A><B>XYZ</B></A>} )
no_error( validator, %q{<A><B>Option 1</B></A>} )
no_error( validator, %q{<A><B>Option 2</B></A>} )
# Attribute values
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<attribute name="B">
<value>VaLuE</value>
</attribute>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A/>} )
error( validator, %q{<A B=""/>} )
error( validator, %q{<A B="Lala"/>} )
no_error( validator, %q{<A B="VaLuE"/>} )
# Attribute values via choice
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<attribute name="B">
<choice>
<value>Option 1</value>
<value>Option 2</value>
</choice>
</attribute>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A B=""/>} )
error( validator, %q{<A B="Value"/>} )
no_error( validator, %q{<A B="Option 1"></A>} )
no_error( validator, %q{<A B="Option 2"/>} )
end
def test_interleave
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<interleave>
<element name="C"/>
<element name="D"/>
<element name="E"/>
</interleave>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B><C/></B></A>} )
error( validator, %q{<A><B><C/><D/><C/></B></A>} )
no_error( validator, %q{<A><B><C/><D/><E/></B></A>} )
no_error( validator, %q{<A><B><E/><D/><C/></B></A>} )
no_error( validator, %q{<A><B><D/><C/><E/></B></A>} )
no_error( validator, %q{<A><B><E/><C/><D/></B></A>} )
error( validator, %q{<A><B><E/><C/><D/><C/></B></A>} )
end
def test_mixed
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<element name="A" xmlns="http://relaxng.org/ns/structure/1.0">
<element name="B">
<mixed>
<element name="D"/>
</mixed>
</element>
</element>
}
validator = REXML::Validation::RelaxNG.new( rng )
no_error( validator, %q{<A><B>Text<D/></B></A>} )
no_error( validator, %q{<A><B><D/>Text</B></A>} )
end
def test_ref_sequence
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<ref name="B"/>
<ref name="B"/>
</element>
</start>
<define name="B">
<element name="B">
<attribute name="X"/>
</element>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
no_error( validator, %q{<A><B X=''/><B X=''/></A>} )
error( validator, %q{<A><B X=''/></A>} )
end
def test_ref_choice
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<choice>
<ref name="B"/>
</choice>
</element>
</start>
<define name="B">
<element name="B"/>
<element name="C"/>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><D/></A>} )
error( validator, %q{<A><B/><C/></A>} )
no_error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><C/></A>} )
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<ref name="B"/>
</element>
</start>
<define name="B">
<choice>
<element name="B"/>
<element name="C"/>
</choice>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><D/></A>} )
error( validator, %q{<A><B/><C/></A>} )
no_error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><C/></A>} )
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<choice>
<ref name="B"/>
<element name="D"/>
</choice>
</element>
</start>
<define name="B">
<element name="B"/>
<element name="C"/>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/><C/></A>} )
no_error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><C/></A>} )
no_error( validator, %q{<A><D/></A>} )
end
def test_ref_zero_plus
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<zeroOrMore>
<ref name="B"/>
</zeroOrMore>
</element>
</start>
<define name="B">
<element name="B">
<attribute name="X"/>
</element>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A/>} )
no_error( validator, %q{<A><B X=''/></A>} )
no_error( validator, %q{<A><B X=''/><B X=''/><B X=''/></A>} )
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<ref name="B"/>
</element>
</start>
<define name="B">
<zeroOrMore>
<element name="B">
<attribute name="X"/>
</element>
</zeroOrMore>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A/>} )
no_error( validator, %q{<A><B X=''/></A>} )
no_error( validator, %q{<A><B X=''/><B X=''/><B X=''/></A>} )
end
def test_ref_one_plus
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<oneOrMore>
<ref name="B"/>
</oneOrMore>
</element>
</start>
<define name="B">
<element name="B">
<attribute name="X"/>
</element>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
error( validator, %q{<A/>} )
no_error( validator, %q{<A><B X=''/></A>} )
no_error( validator, %q{<A><B X=''/><B X=''/><B X=''/></A>} )
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<ref name="B"/>
</element>
</start>
<define name="B">
<oneOrMore>
<element name="B">
<attribute name="X"/>
</element>
</oneOrMore>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
error( validator, %q{<A/>} )
no_error( validator, %q{<A><B X=''/></A>} )
no_error( validator, %q{<A><B X=''/><B X=''/><B X=''/></A>} )
end
def test_ref_interleave
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<interleave>
<ref name="B"/>
</interleave>
</element>
</start>
<define name="B">
<element name="B"/>
<element name="C"/>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
error( validator, %q{<A><C/></A>} )
error( validator, %q{<A><C/><C/></A>} )
no_error( validator, %q{<A><B/><C/></A>} )
no_error( validator, %q{<A><C/><B/></A>} )
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<ref name="B"/>
</element>
</start>
<define name="B">
<interleave>
<element name="B"/>
<element name="C"/>
</interleave>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
error( validator, %q{<A><C/></A>} )
error( validator, %q{<A><C/><C/></A>} )
no_error( validator, %q{<A><B/><C/></A>} )
no_error( validator, %q{<A><C/><B/></A>} )
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<interleave>
<ref name="B"/>
<ref name="C"/>
</interleave>
</element>
</start>
<define name="B">
<element name="B"/>
</define>
<define name="C">
<element name="C"/>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A><B/></A>} )
error( validator, %q{<A><C/></A>} )
error( validator, %q{<A><C/><C/></A>} )
no_error( validator, %q{<A><B/><C/></A>} )
no_error( validator, %q{<A><C/><B/></A>} )
end
def test_ref_recurse
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<ref name="B"/>
</element>
</start>
<define name="B">
<element name="B">
<optional>
<ref name="B"/>
</optional>
</element>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
error( validator, %q{<A></A>} )
no_error( validator, %q{<A><B/></A>} )
no_error( validator, %q{<A><B><B/></B></A>} )
end
def test_ref_optional
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<optional>
<ref name="B"/>
</optional>
</element>
</start>
<define name="B">
<element name="B">
</element>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
no_error( validator, %q{<A></A>} )
no_error( validator, %q{<A><B/></A>} )
error( validator, %q{<A><B/><B/></A>} )
error( validator, %q{<A><C/></A>} )
rng = %q{
<?xml version="1.0" encoding="UTF-8"?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
<start>
<element name="A">
<ref name="B"/>
</element>
</start>
<define name="B">
<optional>
<element name="B">
</element>
</optional>
</define>
</grammar>
}
validator = REXML::Validation::RelaxNG.new( rng )
no_error( validator, %q{<A></A>} )
no_error( validator, %q{<A><B/></A>} )
error( validator, %q{<A><B/><B/></A>} )
error( validator, %q{<A><C/></A>} )
end
def error( validator, source )
parser = REXML::Parsers::TreeParser.new( source )
parser.add_listener( validator.reset )
assert_raise( REXML::Validation::ValidationException,
"Expected a validation error" ) { parser.parse }
end
def no_error( validator, source )
parser = REXML::Parsers::TreeParser.new( source )
parser.add_listener( validator.reset )
assert_nothing_raised { parser.parse }
end
end

View file

@ -0,0 +1,33 @@
#!/usr/bin/env ruby
#
# Created by Henrik Mårtensson on 2007-02-18.
# Copyright (c) 2007. All rights reserved.
require "rexml/document"
require "test/unit"
class TestXmlDeclaration < Test::Unit::TestCase
def setup
xml = <<-'END_XML'
<?xml encoding= 'UTF-8' standalone='yes'?>
<root>
</root>
END_XML
@doc = REXML::Document.new xml
@root = @doc.root
@xml_declaration = @doc.children[0]
end
def test_xml_declaration_is_first_child
assert_kind_of(REXML::XMLDecl, @xml_declaration)
end
def test_xml_declaration_has_document_as_parent
assert_kind_of(REXML::Document, @xml_declaration.parent)
end
def test_xml_declaration_has_sibling
assert_kind_of(REXML::XMLDecl, @root.previous_sibling.previous_sibling)
assert_kind_of(REXML::Element, @xml_declaration.next_sibling.next_sibling)
end
end

1055
test/rexml/test_xpath.rb Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,89 @@
# rexml_xpath_attribute_query.rb
# May 16, 2007
#
require 'test/unit'
require 'rexml/document'
class TestRexmlXpathAttributeQuery < Test::Unit::TestCase
# xmlstr1 and xmlstr2 only differ in the second line - namespaces in the root element
@@xmlstr1 = '<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:gCal="http://schemas.google.com/gCal/2005">
<id>http://www.google.com/calendar/feeds/me%40gmail.com</id>
<entry>
<id>http://www.google.com/calendar/feeds/me%40gmail.com/me%40gmail.com</id>
<published>2007-05-16T13:42:27.942Z</published>
<updated>2007-05-15T03:29:28.000Z</updated>
<title type="text">My Calendar</title>
<link rel="alternate" type="application/atom+xml" href="http://www.google.com/calendar/feeds/me%40gmail.com/private/full"/>
<link rel="http://schemas.google.com/acl/2007#accessControlList" type="application/atom+xml" href="http://www.google.com/calendar/feeds/me%40gmail.com/acl/full"/>
<link rel="self" type="application/atom+xml" href="http://www.google.com/calendar/feeds/me%40gmail.com/me%40gmail.com"/>
<author>
<name>Me</name>
<email>me@gmail.com</email>
</author>
</entry>
</feed>'
@@xmlstr2 = '<?xml version="1.0" encoding="UTF-8"?>
<feed>
<id>http://www.google.com/calendar/feeds/me%40gmail.com</id>
<entry>
<id>http://www.google.com/calendar/feeds/me%40gmail.com/me%40gmail.com</id>
<published>2007-05-16T13:42:27.942Z</published>
<updated>2007-05-15T03:29:28.000Z</updated>
<title type="text">My Calendar</title>
<link rel="alternate" type="application/atom+xml" href="http://www.google.com/calendar/feeds/me%40gmail.com/private/full"/>
<link rel="http://schemas.google.com/acl/2007#accessControlList" type="application/atom+xml" href="http://www.google.com/calendar/feeds/me%40gmail.com/acl/full"/>
<link rel="self" type="application/atom+xml" href="http://www.google.com/calendar/feeds/me%40gmail.com/me%40gmail.com"/>
<author>
<name>Me</name>
<email>me@gmail.com</email>
</author>
</entry>
</feed>'
# Fails
def test_xpath_query
do_test @@xmlstr1
end
# Passes
def test_xpath_query_no_namespace
do_test @@xmlstr2
end
def do_test(xmlString)
hrefs = [
"http://www.google.com/calendar/feeds/me%40gmail.com/private/full",
"http://www.google.com/calendar/feeds/me%40gmail.com/acl/full",
"http://www.google.com/calendar/feeds/me%40gmail.com/me%40gmail.com"
]
ctr=0
REXML::Document.new(xmlString).elements.each("feed/entry") do |element|
@alternate_link = element.elements["link[@rel='alternate']"]
assert_not_nil( @alternate_link )
assert_equal( hrefs[ctr], @alternate_link.attributes['href'])
ctr += 1
end
end
def test_another_way
doc = REXML::Document.new(@@xmlstr1)
hrefs = [
"http://www.google.com/calendar/feeds/me%40gmail.com/private/full",
"http://www.google.com/calendar/feeds/me%40gmail.com/acl/full",
"http://www.google.com/calendar/feeds/me%40gmail.com/me%40gmail.com"
]
ctr=0
REXML::XPath.each(doc, "//link[@rel='alternate']") do |element|
@alternate_link = element
assert_not_nil @alternate_link
assert_equal( hrefs[ctr], @alternate_link.attributes['href'])
ctr += 1
end
end
end

View file

@ -0,0 +1,42 @@
require "test/unit/testcase"
require "test/unit/ui/console/testrunner"
require "rexml/document"
class XPathAxesTester < Test::Unit::TestCase
include REXML
SOURCE = <<-EOF
<a id='1'>
<e id='2'>
<f id='3'/>
<f id='4'/>
<f id='5'/>
<f id='6'/>
</e>
</a>
EOF
def setup
@@doc = Document.new(SOURCE) unless defined? @@doc
end
def test_preceding_sibling_axis
context = XPath.first(@@doc,"/a/e/f[last()]")
assert_equal "6", context.attributes["id"]
prev = XPath.first(context, "preceding-sibling::f")
assert_equal "5", prev.attributes["id"]
prev = XPath.first(context, "preceding-sibling::f[1]")
assert_equal "5", prev.attributes["id"]
prev = XPath.first(context, "preceding-sibling::f[2]")
assert_equal "4", prev.attributes["id"]
prev = XPath.first(context, "preceding-sibling::f[3]")
assert_equal "3", prev.attributes["id"]
end
end
#Test::Unit::UI::Console::TestRunner.run(XPathAxesTester.suite)

View file

@ -0,0 +1,80 @@
require "test/unit/testcase"
require "rexml/document"
require "rexml/xpath"
require "rexml/parsers/xpathparser"
class XPathPredicateTester < Test::Unit::TestCase
include REXML
SRC=<<-EOL
<article>
<section role="subdivision" id="1">
<para>free flowing text.</para>
</section>
<section role="division">
<section role="subdivision" id="2">
<para>free flowing text.</para>
</section>
<section role="division">
<para>free flowing text.</para>
</section>
</section>
</article>
EOL
def setup
@doc = REXML::Document.new( SRC )
@parser = REXML::Parsers::XPathParser.new
end
def test_predicates_parent
path = '//section[../self::section[@role="division"]]'
m = do_path( path )
assert_equal( 2, m.size )
assert_equal( "2", m[0].attributes["id"] )
assert_nil( m[1].attributes["id"] )
end
def test_predicates_single
path = '//section[@role="subdivision" and not(../self::section[@role="division"])]'
m = do_path( path )
assert_equal( 1, m.size )
assert_equal( "1", m[0].attributes["id"] )
end
def test_predicates_multi
path = '//section[@role="subdivision"][not(../self::section[@role="division"])]'
m = do_path( path )
assert_equal( 1, m.size )
assert_equal( "1", m[0].attributes["id"] )
end
def do_path( path )
m = REXML::XPath.match( @doc, path )
#puts path, @parser.parse( path ).inspect
return m
end
def test_get_no_siblings_terminal_nodes
source = <<-XML
<a>
<b number='1' str='abc'>TEXT1</b>
<c number='1'/>
<c number='2' str='def'>
<b number='3'/>
<d number='1' str='abc'>TEXT2</d>
<b number='2'><!--COMMENT--></b>
</c>
</a>
XML
doc = REXML::Document.new(source)
predicate = "count(child::node()|" +
"following-sibling::node()|" +
"preceding-sibling::node())=0"
m = REXML::XPath.match(doc, "/descendant-or-self::node()[#{predicate}]")
assert_equal( [REXML::Text.new("TEXT1"),
REXML::Text.new("TEXT2"),
REXML::Comment.new("COMMENT")],
m )
end
end

View file

@ -0,0 +1,72 @@
require 'test/unit'
require 'rexml/document'
require 'rexml/element'
require 'rexml/xpath'
class XpathTestCase < Test::Unit::TestCase
def setup
@doc = REXML::Document.new
end
def tear_down
end
def test_text_as_element
node1 = REXML::Element.new('a', @doc)
node2 = REXML::Element.new('b', node1)
textnode = REXML::Text.new('test', false, node2)
assert_equal(1, @doc.elements.size, "doc owns 1 element node1")
assert_same(node1, @doc.elements[1], "doc owns 1 element node1")
assert_equal(1, node1.elements.size, "node1 owns 1 element node2")
assert_same(node2, node1.elements[1], "node1 owns 1 element node2")
assert_equal(1, node2.size, "node2 owns 1 text element")
end
def test_text_in_xpath_query
node1 = REXML::Element.new('a', @doc)
node2 = REXML::Element.new('b', node1)
textnode = REXML::Text.new('test', false, node2)
textnode.parent = node2 # should be unnecessary
nodes = @doc.get_elements('//b')
assert_equal(1, nodes.size, "document has one element")
# why doesn't this query work right?
nodes = REXML::XPath.match(@doc, '//text()')
assert_equal(1, nodes.size, "//text() should yield one Text element")
assert_equal(REXML::Text, nodes[0].class)
end
def test_comment_in_xpath_query
node1 = REXML::Element.new('a', @doc)
node2 = REXML::Element.new('b', node1)
commentnode = REXML::Comment.new('test', node2)
nodes = REXML::XPath.match(@doc, '//comment()')
assert_equal(1, nodes.size, "//comment() should yield one Comment element")
assert_same commentnode, nodes[0]
end
def test_parentage
node1 = REXML::Element.new('a', @doc)
assert_same(@doc, node1.parent, "node1 parent is document")
node2 = REXML::Element.new('b', node1)
assert_same(node1, node2.parent, "node2 parent is node1")
textnode = REXML::Text.new('test', false, node2)
# why isn't the text's parent node2?
# Also look at Comment, etc.
assert_same(node2, textnode.parent)
comment = REXML::Comment.new('Test comment', node2)
assert_same(node2, comment.parent)
end
def test_ancestors
node1 = REXML::Element.new('a', @doc)
node2 = REXML::Element.new('b', node1)
textnode = REXML::Text.new('test', false, node2)
#textnode.parent = node2 # should be unnecessary
assert_same node2, textnode.parent
nodes = @doc.get_elements('//b/ancestor::*')
assert_equal(1, nodes.size, "<b> has one element ancestor")
nodes = @doc.get_elements('//b/ancestor::node()')
assert_equal(2, nodes.size, "<b> has two node ancestors")
assert nodes[1].kind_of?(REXML::Document)
end
end