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:
parent
045491d5be
commit
91ed484f92
89 changed files with 34722 additions and 0 deletions
|
@ -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):
|
||||
|
|
BIN
test/rexml/data/LostineRiver.kml.gz
Normal file
BIN
test/rexml/data/LostineRiver.kml.gz
Normal file
Binary file not shown.
29
test/rexml/data/ProductionSupport.xml
Normal file
29
test/rexml/data/ProductionSupport.xml
Normal 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
25
test/rexml/data/axis.xml
Normal 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
5
test/rexml/data/bad.xml
Normal 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
11
test/rexml/data/basic.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<foo>
|
||||
<bar>
|
||||
<baz/>
|
||||
<cheese/>
|
||||
<baz/>
|
||||
<cheese/>
|
||||
<baz/>
|
||||
</bar>
|
||||
</foo>
|
47
test/rexml/data/basicupdate.xml
Normal file
47
test/rexml/data/basicupdate.xml
Normal 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>
|
20
test/rexml/data/broken.rss
Normal file
20
test/rexml/data/broken.rss
Normal 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>
|
70
test/rexml/data/contents.xml
Normal file
70
test/rexml/data/contents.xml
Normal 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
12
test/rexml/data/dash.xml
Normal 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>
|
6
test/rexml/data/defaultNamespace.xml
Normal file
6
test/rexml/data/defaultNamespace.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<a xmlns="http://dummyNamespace/">
|
||||
<b>
|
||||
<c>Hello</c>
|
||||
</b>
|
||||
</a>
|
34
test/rexml/data/doctype_test.xml
Normal file
34
test/rexml/data/doctype_test.xml
Normal 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/>
|
542
test/rexml/data/documentation.xml
Normal file
542
test/rexml/data/documentation.xml
Normal 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&max=50&daysback=90&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 <-> 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 '<' 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
296
test/rexml/data/euc.xml
Normal 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)<<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>
|
28
test/rexml/data/evaluate.xml
Normal file
28
test/rexml/data/evaluate.xml
Normal 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
29
test/rexml/data/fibo.xml
Normal 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
10
test/rexml/data/foo.xml
Normal 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>
|
156
test/rexml/data/google.2.xml
Normal file
156
test/rexml/data/google.2.xml
Normal 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, 'No campaigns selected.');'>
|
||||
<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(" <input
|
||||
type\u003d\"checkbox\" name\u003d\"toggleAll\"
|
||||
onclick\u003d\"rowToggleAll(this);\" title\u003d\"Select or
|
||||
de-select all campaigns on this page\"> ");</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&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&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&gsessionid=ezmXK9aaXnI#campaigns'
|
||||
class='bluelink' shape='rect'>Current Budget</a>
|
||||
<span style='white-space: nowrap'>
|
||||
<a href='/support/bin/answer.py?answer=6312&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&gsessionid=ezmXK9aaXnI#campaigns'
|
||||
class='bluelink' shape='rect'>Clicks</a>
|
||||
<a href='CampaignSummary?campaignsummaryt=-3%3Aa&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&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&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&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&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&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&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
21
test/rexml/data/id.xml
Normal 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>
|
4
test/rexml/data/iso8859-1.xml
Normal file
4
test/rexml/data/iso8859-1.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version='1.0' encoding='ISO-8859-1'?>
|
||||
<booh>
|
||||
<image caption='andrè is nice'/>
|
||||
</booh>
|
2
test/rexml/data/jaxen24.xml
Normal file
2
test/rexml/data/jaxen24.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<body><p><span></span></p><div></div></body>
|
15
test/rexml/data/jaxen3.xml
Normal file
15
test/rexml/data/jaxen3.xml
Normal 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
11
test/rexml/data/lang.xml
Normal 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
18
test/rexml/data/lang0.xml
Normal 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>
|
27
test/rexml/data/message.xml
Normal file
27
test/rexml/data/message.xml
Normal 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>
|
244
test/rexml/data/moreover.xml
Normal file
244
test/rexml/data/moreover.xml
Normal 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
6850
test/rexml/data/much_ado.xml
Normal file
File diff suppressed because it is too large
Load diff
18
test/rexml/data/namespaces.xml
Normal file
18
test/rexml/data/namespaces.xml
Normal 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
67
test/rexml/data/nitf.xml
Normal 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's New Media Group, said Napster was used by "the full spectrum of PC users, not just the youth with time on their hands and a passion for music."</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'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>
|
18
test/rexml/data/numbers.xml
Normal file
18
test/rexml/data/numbers.xml
Normal 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>
|
13971
test/rexml/data/ofbiz-issues-full-177.xml
Normal file
13971
test/rexml/data/ofbiz-issues-full-177.xml
Normal file
File diff suppressed because it is too large
Load diff
13
test/rexml/data/pi.xml
Normal file
13
test/rexml/data/pi.xml
Normal 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
6
test/rexml/data/pi2.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0"?>
|
||||
<a>
|
||||
<b>foo</b>
|
||||
<?toc order-by="x"?>
|
||||
<c>bar</c>
|
||||
</a>
|
1
test/rexml/data/project.xml
Normal file
1
test/rexml/data/project.xml
Normal 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>
|
2
test/rexml/data/simple.xml
Normal file
2
test/rexml/data/simple.xml
Normal file
|
@ -0,0 +1,2 @@
|
|||
<?xml version="1.0" ?>
|
||||
<root><a>a</a><b>b</b><c><d>d</d></c></root>
|
4
test/rexml/data/stream_accents.xml
Normal file
4
test/rexml/data/stream_accents.xml
Normal 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
BIN
test/rexml/data/t63-1.xml
Normal file
Binary file not shown.
2828
test/rexml/data/t63-2.svg
Normal file
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
31
test/rexml/data/t75.xml
Normal 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'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>
|
683
test/rexml/data/test/tests.xml
Normal file
683
test/rexml/data/test/tests.xml
Normal 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 > 2 > 1">false</valueOf>
|
||||
<!-- 3 >= (2 >= 2) is true -->
|
||||
<valueOf select="3 >= 2 >= 2">false</valueOf>
|
||||
<!-- 1 < (2 < 3) is false -->
|
||||
<valueOf select="1 < 2 < 3">true</valueOf>
|
||||
<!-- 0 <= (2 <= 3) is true -->
|
||||
<valueOf select="2 <= 2 <= 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 < *">true</valueOf>
|
||||
<valueOf select="55 <= *">true</valueOf>
|
||||
<valueOf select="69 < *">false</valueOf>
|
||||
<valueOf select="-2 > *">true</valueOf>
|
||||
<valueOf select="-3 >= *">true</valueOf>
|
||||
<valueOf select="-4 >= *">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 > nr/@value">false</valueOf>
|
||||
<valueOf select="55 > nr/@value">false</valueOf>
|
||||
<valueOf select="55 >= nr/@value">true</valueOf>
|
||||
<valueOf select="1000000 > 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() < 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 
 b 
 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>
|
369
test/rexml/data/test/tests.xsl
Normal file
369
test/rexml/data/test/tests.xsl
Normal 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 & 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 <bob@werken.com> and
|
||||
* James Strachan <jstrachan@apache.org>. For more information on the
|
||||
* Jaxen Project, please see <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>
|
22
test/rexml/data/testNamespaces.xml
Normal file
22
test/rexml/data/testNamespaces.xml
Normal 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>
|
64
test/rexml/data/testsrc.xml
Normal file
64
test/rexml/data/testsrc.xml
Normal 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
10
test/rexml/data/text.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0"?>
|
||||
<foo>
|
||||
<bar>
|
||||
baz
|
||||
<cheese id="3"/>
|
||||
baz
|
||||
<cheese/>
|
||||
baz
|
||||
</bar>
|
||||
</foo>
|
BIN
test/rexml/data/ticket_110_utf16.xml
Normal file
BIN
test/rexml/data/ticket_110_utf16.xml
Normal file
Binary file not shown.
4
test/rexml/data/ticket_61.xml
Normal file
4
test/rexml/data/ticket_61.xml
Normal file
File diff suppressed because one or more lines are too long
590
test/rexml/data/ticket_68.xml
Normal file
590
test/rexml/data/ticket_68.xml
Normal 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>
|
678
test/rexml/data/tutorial.xml
Normal file
678
test/rexml/data/tutorial.xml
Normal 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 = <<EOF
|
||||
<mydoc>
|
||||
<someelement attribute="nanoo">Text, text, text</someelement>
|
||||
</mydoc>
|
||||
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"><inventory title="OmniCorp Store #45x10^3">
|
||||
<section name="health">
|
||||
<item upc="123456789" stock="12">
|
||||
<name>Invisibility Cream</name>
|
||||
<price>14.50</price>
|
||||
<description>Makes you invisible</description>
|
||||
</item>
|
||||
<item upc="445322344" stock="18">
|
||||
<name>Levitation Salve</name>
|
||||
<price>23.99</price>
|
||||
<description>Levitate yourself for up to 3 hours per application</description>
|
||||
</item>
|
||||
</section>
|
||||
<section name="food">
|
||||
<item upc="485672034" stock="653">
|
||||
<name>Blork and Freen Instameal</name>
|
||||
<price>4.95</price>
|
||||
<description>A tasty meal in a tablet; just add water</description>
|
||||
</item>
|
||||
<item upc="132957764" stock="44">
|
||||
<name>Grob winglets</name>
|
||||
<price>3.56</price>
|
||||
<description>Tender winglets of Grob. Just add water</description>
|
||||
</item>
|
||||
</section>
|
||||
</inventory></example>
|
||||
|
||||
<example title="Accessing Elements">doc = Document.new File.new("mydoc.xml")
|
||||
doc.elements.each("inventory/section") { |element| puts element.attributes["name"] }
|
||||
# -> health
|
||||
# -> food
|
||||
doc.elements.each("*/section/item") { |element| puts element.attributes["upc"] }
|
||||
# -> 123456789
|
||||
# -> 445322344
|
||||
# -> 485672034
|
||||
# -> 132957764
|
||||
root = doc.root
|
||||
puts root.attributes["title"]
|
||||
# -> OmniCorp Store #45x10^3
|
||||
puts root.elements["section/item[@stock='44']"].attributes["upc"]
|
||||
# -> 132957764
|
||||
puts root.elements["section"].attributes["name"]
|
||||
# -> health (returns the first encountered matching element)
|
||||
puts root.elements[1].attributes["name"]
|
||||
# -> 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 <item>
|
||||
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 '<!DOCTYPE foo [
|
||||
<!ENTITY ent "replace">
|
||||
]><a>&ent;</a>'
|
||||
doc.root.text #-> "replace"
|
||||
</example>
|
||||
|
||||
<p>When you write the document back out, REXML replaces the values
|
||||
with the entity reference:</p>
|
||||
|
||||
<example>doc.to_s
|
||||
# Generates:
|
||||
# <!DOCTYPE foo [
|
||||
# <!ENTITY ent "replace">
|
||||
# ]><a>&ent;</a></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 '<!DOCTYPE foo [
|
||||
<!ENTITY ent "replace">
|
||||
]><a>replace &ent;</a>'
|
||||
doc.root.text #-> "replace replace"
|
||||
</example>
|
||||
|
||||
<p>Well, REXML does the only thing it can:</p>
|
||||
|
||||
<example>doc.to_s
|
||||
# Generates:
|
||||
# <!DOCTYPE foo [
|
||||
# <!ENTITY ent "replace">
|
||||
# ]><a>&ent; &ent;</a></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( '<!DOCTYPE foo
|
||||
[ <!ENTITY ent "replace"> ]><a>replace
|
||||
&ent;</a>' ) doc.to_s # Generates: # <!DOCTYPE foo [ #
|
||||
<!ENTITY ent "replace"> # ]><a><emphasis>replace
|
||||
&ent;</emphasis></a> doc.root.text #-> Now accessed,
|
||||
entities have been resolved doc.to_s # Generates: # <!DOCTYPE foo [
|
||||
# <!ENTITY ent "replace"> # ]><a><emphasis>&ent;
|
||||
&ent;</emphasis></a></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('<!DOCTYPE
|
||||
foo [ <!ENTITY ent "replace"> ]><a>replace
|
||||
&ent;</a>',<emphasis>{:raw=>:all})</emphasis>
|
||||
doc.root.text #-> "replace &ent;" doc.to_s # Generates: #
|
||||
<!DOCTYPE foo [ # <!ENTITY ent "replace"> #
|
||||
]><a>replace &ent;</a></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"=>"10"}
|
||||
# does the same, but also sets attribute "id" of el2 to "10"
|
||||
el3 = Element.new "blah"
|
||||
el1.elements << 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!"
|
||||
# -> <myelement>Hello world!</myelement>
|
||||
el1.add_text "Hello dolly"
|
||||
# -> <myelement>Hello world!Hello dolly</element>
|
||||
el1.add Text.new("Goodbye")
|
||||
# -> <myelement>Hello world!Hello dollyGoodbye</element>
|
||||
el1 << Text.new(" cruel world")
|
||||
# -> <myelement>Hello world!Hello dollyGoodbye cruel world</element></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.
|
||||
 If you're adding standard 7-bit ASCII, which is most common, you
|
||||
don't have to worry.  If you're using ISO-8859-1 text (characters
|
||||
above 0x80), you must convert it to UTF-8 before adding it to an
|
||||
element.  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.  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 "<a/>"
|
||||
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 "<a><one/><three/></a>"
|
||||
doc.root[1,0] = Element.new "two"
|
||||
# -> <a><one/><two/><three/></a>
|
||||
three = doc.elements["a/three"]
|
||||
doc.root.insert_after three, Element.new "four"
|
||||
# -> <a><one/><two/><three/><four/></a>
|
||||
# A convenience method allows you to insert before/after an XPath:
|
||||
doc.root.insert_after( "//one", Element.new("one-five") )
|
||||
# -> <a><one/><one-five/><two/><three/><four/></a>
|
||||
# Another convenience method allows you to insert after/before an element:
|
||||
four = doc.elements["//four"]
|
||||
four.previous_sibling = Element.new("three-five")
|
||||
# -> <a><one/><one-five/><two/><three/><three-five/><four/></a></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( "<?xml version='1.0?>
|
||||
<!DOCTYPE foo SYSTEM 'foo.dtd' [
|
||||
<!ENTITY % s "Sean">
|
||||
]>
|
||||
<a/>"
|
||||
t = Text.new( "Sean", false, nil, false )
|
||||
doc.root.text = t
|
||||
t.to_s # -> &s;
|
||||
t = Text.new( "Sean", false, nil, true )
|
||||
doc.root.text = t
|
||||
t.to_s # -> 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( "&", 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 => %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 => :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><<( String
|
||||
)</code> to the <code>write</code> method of any object. In Ruby, both
|
||||
IO instances (File) and String instances support <<.</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 #-> <foo/>
|
||||
doc << XMLDecl.new
|
||||
doc.to_s #-> <?xml version='1.0'?><foo/></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>&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 => %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 &, <, >, ", 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
|
||||
&, <, or > in the document source, it will generate a
|
||||
parsing error.</p>
|
||||
|
||||
<example title="Entity processing">bad_source = "<a>Cats & dogs</a>"
|
||||
good_source = "<a>Cats &amp; &#100;ogs</a>"
|
||||
doc = REXML::Document.new bad_source
|
||||
# Generates a parse error
|
||||
doc = REXML::Document.new good_source
|
||||
puts doc.root.text
|
||||
# -> "Cats & &#100;ogs"
|
||||
doc.root.write $stdout
|
||||
# -> "<a>Cats &amp; &#100;ogs</a>"
|
||||
doc.root.attributes["m"] = "x'y\"z"
|
||||
puts doc.root.attributes["m"]
|
||||
# -> "x'y\"z"
|
||||
doc.root.write $stdout
|
||||
# -> "<a m='x&apos;y&quot;z'>Cats &amp; &#100;ogs</a>"</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 = "<a xmlns:x='foo' xmlns:y='bar'><x:b id='1'/><y:b id='2'/></a>"
|
||||
doc = Document.new source
|
||||
doc.elements["/a/x:b"].attributes["id"] # -> '1'
|
||||
XPath.first(doc, "/a/m:b", {"m"=>"bar"}).attributes["id"] # -> '2'
|
||||
doc.elements["//x:b"].prefix # -> 'x'
|
||||
doc.elements["//x:b"].namespace # -> 'foo'
|
||||
XPath.first(doc, "//m:b", {"m"=>"bar"}).prefix # -> '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: # # <td class='abc'>text</td> # # We use:
|
||||
# # find_node(root, 'td', {'class' => '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: # # <table> # <tr> #
|
||||
<td>A</td> # <td>B</td> #
|
||||
<td>C</td> # </tr> # <tr> #
|
||||
<td>A.1</td> # <td>B.1</td> #
|
||||
<td>C.1</td> # </tr> # <tr> #
|
||||
<td>A.2</td> # <td>B.2</td> #
|
||||
<td>C.2</td> # </tr> # </table> # # 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 < 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>
|
6
test/rexml/data/underscore.xml
Normal file
6
test/rexml/data/underscore.xml
Normal 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
42
test/rexml/data/web.xml
Normal 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
7
test/rexml/data/web2.xml
Normal 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
202
test/rexml/data/working.rss
Normal 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>
|
||||
<pre>
|
||||
&lt;richlowe&gt; blah.
|
||||
&lt;richlowe&gt; that's what I say.
|
||||
&lt;pabs&gt; if i say it too then what happens?
|
||||
&lt;richlowe&gt; then "that's what we say"
|
||||
&lt;richlowe&gt; duh.
|
||||
&lt;pabs&gt; what if i say it, then retract it?
|
||||
&lt;richlowe&gt; Did they teach you nothing in school!
|
||||
&lt;richlowe&gt; "that's what I say, and he said"
|
||||
&lt;pabs&gt; :(
|
||||
&lt;pabs&gt; okay what if i say it, retract it, but then plan on saying it
|
||||
again at some point in the indeterminite future?
|
||||
&lt;richlowe&gt; "that's what I say, and he has said, and will possibly say
|
||||
again"?
|
||||
&lt;pabs&gt; see now that's not concise at all
|
||||
</pre>
|
||||
|
||||
</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>
|
||||
<p>
|
||||
Perhaps <a href='http://www.dash-dash.org/pix/death.jpg'>the image</a>
|
||||
on <a href='http://www.dash-dash.org/'>his site</a> 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.
|
||||
</p>
|
||||
|
||||
</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>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
</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>
|
||||
<p>
|
||||
<a href='http://www.linuxbrit.co.uk/'>Tom</a> has been having a rough
|
||||
couple of weeks. Apparently he's got <a
|
||||
href='http://www.ninds.nih.gov/health_and_medical/disorders/bells_doc.htm'>Bell's
|
||||
Palsy</a> (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 <abbr title='Electronic
|
||||
Card'>E-Card</abbr> or an <a
|
||||
href='mailto:dr_spock@linuxbrit.co.uk'>email</a>.
|
||||
</p>
|
||||
|
||||
</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>
|
||||
<p>
|
||||
Okay, apparently Ed <em>does</em> read this page. :-D
|
||||
</p>
|
||||
|
||||
</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>
|
||||
<p>
|
||||
Ed got married in the Bahamas! Here's a picture from the honeymoon:
|
||||
</p>
|
||||
|
||||
<img src='/files/ed_dolphin.jpg' width='252' height='288'
|
||||
title='Ed on his honeymoon!' alt='Ed on his honeymoon!' />
|
||||
|
||||
<p>
|
||||
(Fortunately he doesn't read this site).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
One other thing. I weigh 186<abbr title='Pounds'>lbs</abbr> now.
|
||||
The <a href='http://www.pablotron.org/weight/'>weight page</a> has been
|
||||
updated.
|
||||
</p>
|
||||
|
||||
</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>
|
||||
<p>
|
||||
Just saw this <acronym title='Uniform Resource Locator'>URL</acronym>
|
||||
on <a href='http://www.diveintomark.org/'>Dive Into
|
||||
Mark</a>:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a
|
||||
href='http://www.google.com/search?q=answer+to+life+the+universe+and+everything'>http://www.google.com/search?q=answer+to+life+the+universe+and+everything</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href='http://www.bbc.co.uk/h2g2/guide/'><acronym title='Hitchhikers
|
||||
Guide to the Galaxy'>H2G2</acronym></a> references never get old for me.
|
||||
</p>
|
||||
|
||||
</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>
|
||||
<p>
|
||||
What a nutty weekend. A friend of mine went to the <acronym
|
||||
title='Emergency Room'>ER</acronym> 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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
I finally got <a href='http://www.raggle.org/'>Raggle</a> 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 <a
|
||||
href='http://www.raggle.org/'>check it out</a> on your own.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href='http://www.pablotron.org/weight/'>The war against obesity</a>
|
||||
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 "Go to the Gym Every Night or Else"
|
||||
week. 2 days down, 5 to go.
|
||||
</p>
|
||||
|
||||
</description>
|
||||
</item>
|
||||
|
||||
</rss>
|
15
test/rexml/data/xmlfile-bug.xml
Normal file
15
test/rexml/data/xmlfile-bug.xml
Normal 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
27
test/rexml/data/xp.tst
Normal 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
80
test/rexml/data/yahoo.xml
Normal 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&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&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&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&p=4yz6x35&n=4126112&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&p=4yz6x35&n=4126112&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&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&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
50
test/rexml/listener.rb
Normal 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
|
||||
|
198
test/rexml/test_attributes.rb
Normal file
198
test/rexml/test_attributes.rb
Normal 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'2''/)
|
||||
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 & ampersand only')
|
||||
end
|
||||
|
||||
def test_amp_and_lf_attributes
|
||||
attr_test('name','value with LF 
 & 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
|
34
test/rexml/test_attributes_mixin.rb
Normal file
34
test/rexml/test_attributes_mixin.rb
Normal 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
|
46
test/rexml/test_changing_encoding.rb
Normal file
46
test/rexml/test_changing_encoding.rb
Normal 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
581
test/rexml/test_contrib.rb
Normal 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',"'",'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ødef'
|
||||
a = Text.new( txt,false,nil,true )
|
||||
f.write(a,out="")
|
||||
assert_equal( txt, out )
|
||||
|
||||
txt = '<sean><russell>abcø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&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
1382
test/rexml/test_core.rb
Normal file
File diff suppressed because it is too large
Load diff
67
test/rexml/test_doctype_mixin.rb
Normal file
67
test/rexml/test_doctype_mixin.rb
Normal 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
107
test/rexml/test_elements.rb
Normal 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
|
92
test/rexml/test_encoding.rb
Normal file
92
test/rexml/test_encoding.rb
Normal 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
|
59
test/rexml/test_encoding_2.rb
Normal file
59
test/rexml/test_encoding_2.rb
Normal 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
148
test/rexml/test_entity.rb
Normal 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("&", REXML::Text.new("&", false, nil, true).to_s)
|
||||
#assert_equal("&", REXML::Text.new("&", false, false).to_s)
|
||||
end
|
||||
|
||||
def test_single_pass_unnormalization # ticket 123
|
||||
assert_equal '&&', REXML::Text::unnormalize('&amp;&')
|
||||
end
|
||||
end
|
223
test/rexml/test_functions.rb
Normal file
223
test/rexml/test_functions.rb
Normal 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
|
32
test/rexml/test_functions_number.rb
Normal file
32
test/rexml/test_functions_number.rb
Normal 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
126
test/rexml/test_jaxen.rb
Normal 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
101
test/rexml/test_light.rb
Normal 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
|
11
test/rexml/test_lightparser.rb
Normal file
11
test/rexml/test_lightparser.rb
Normal 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
207
test/rexml/test_listener.rb
Normal 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;</string>}
|
||||
assert_equal( "<><>", @listener.parse( t5 ),
|
||||
"Entity reference" )
|
||||
end
|
||||
|
||||
def test_character_reference
|
||||
return unless defined? @listener
|
||||
# Character reference.
|
||||
t6 = %Q{<string>
</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>
</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
|
38
test/rexml/test_martin_fowler.rb
Normal file
38
test/rexml/test_martin_fowler.rb
Normal 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
|
58
test/rexml/test_notationdecl_mixin.rb
Normal file
58
test/rexml/test_notationdecl_mixin.rb
Normal 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
|
23
test/rexml/test_notationdecl_parsetest.rb
Normal file
23
test/rexml/test_notationdecl_parsetest.rb
Normal 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
101
test/rexml/test_order.rb
Normal 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
|
||||
|
40
test/rexml/test_preceding_sibling.rb
Normal file
40
test/rexml/test_preceding_sibling.rb
Normal 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
|
100
test/rexml/test_pullparser.rb
Normal file
100
test/rexml/test_pullparser.rb
Normal 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 <<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
|
15
test/rexml/test_rexml_issuezilla.rb
Normal file
15
test/rexml/test_rexml_issuezilla.rb
Normal 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
286
test/rexml/test_sax.rb
Normal 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>ü</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>ü</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
104
test/rexml/test_stream.rb
Normal 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
|
56
test/rexml/test_ticket_80.rb
Normal file
56
test/rexml/test_ticket_80.rb
Normal 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
|
||||
#------------------------------------------------------------------------------
|
790
test/rexml/test_validation_rng.rb
Normal file
790
test/rexml/test_validation_rng.rb
Normal 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
|
33
test/rexml/test_xml_declaration_parent_child.rb
Normal file
33
test/rexml/test_xml_declaration_parent_child.rb
Normal 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
1055
test/rexml/test_xpath.rb
Normal file
File diff suppressed because it is too large
Load diff
89
test/rexml/test_xpath_attribute_query.rb
Normal file
89
test/rexml/test_xpath_attribute_query.rb
Normal 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
|
42
test/rexml/test_xpath_msw.rb
Normal file
42
test/rexml/test_xpath_msw.rb
Normal 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)
|
||||
|
80
test/rexml/test_xpath_pred.rb
Normal file
80
test/rexml/test_xpath_pred.rb
Normal 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
|
72
test/rexml/test_xpathtext.rb
Normal file
72
test/rexml/test_xpathtext.rb
Normal 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
|
Loading…
Add table
Add a link
Reference in a new issue