1
/* Copyright 2003-2005 Elliotte Rusty Harold
3
This library is free software; you can redistribute it and/or modify
4
it under the terms of version 2.1 of the GNU Lesser General Public
5
License as published by the Free Software Foundation.
7
This library is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU Lesser General Public License for more details.
12
You should have received a copy of the GNU Lesser General Public
13
License along with this library; if not, write to the
14
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15
Boston, MA 02111-1307 USA
17
You can contact Elliotte Rusty Harold by sending e-mail to
18
elharo@metalab.unc.edu. Please include the word "XOM" in the
19
subject line. The XOM home page is located at http://www.xom.nu/
26
import java.io.IOException;
27
import java.io.StringWriter;
29
import nu.xom.Attribute;
30
import nu.xom.Builder;
31
import nu.xom.Comment;
32
import nu.xom.DocType;
33
import nu.xom.Document;
34
import nu.xom.Element;
35
import nu.xom.ParsingException;
36
import nu.xom.ProcessingInstruction;
37
import nu.xom.converters.SAXConverter;
39
import org.xml.sax.Attributes;
40
import org.xml.sax.ContentHandler;
41
import org.xml.sax.Locator;
42
import org.xml.sax.SAXException;
43
import org.xml.sax.ext.LexicalHandler;
44
import org.xml.sax.helpers.DefaultHandler;
48
* Basic tests for conversion from XOM trees
49
* to SAX ContentHandlers.
52
* @author Elliotte Rusty Harold
56
public class SAXConverterTest extends XOMTestCase {
59
public SAXConverterTest(String name) {
64
private DefaultHandler handler;
65
private SAXConverter converter;
66
private Builder builder = new Builder();
69
protected void setUp() {
70
handler = new DefaultHandler();
71
converter = new SAXConverter(handler);
75
public void testGetContentHandler() {
76
assertEquals(handler, converter.getContentHandler());
80
public void testSetContentHandler() {
82
handler = new DefaultHandler();
83
converter.setContentHandler(handler);
84
assertEquals(handler, converter.getContentHandler());
87
converter.setContentHandler(null);
88
fail("Allowed null ContentHandler");
90
catch (NullPointerException success) {
97
public void testSetAndGetLexicalHandler() {
99
LexicalHandler handler = new XMLWriter();
100
converter.setLexicalHandler(handler);
101
assertEquals(handler, converter.getLexicalHandler());
103
converter.setLexicalHandler(null);
104
assertNull(converter.getLexicalHandler());
109
private void convertAndCompare(Document doc)
110
throws IOException, SAXException, ParsingException {
112
StringWriter result = new StringWriter();
113
XMLWriter handler = new XMLWriter(result);
114
converter.setContentHandler(handler);
115
converter.setLexicalHandler(handler);
116
converter.convert(doc);
119
String convertedDoc = result.toString();
120
Document rebuiltDoc = builder.build(convertedDoc, doc.getBaseURI());
121
assertEquals(doc, rebuiltDoc);
126
public void testSimplestDoc()
127
throws IOException, SAXException, ParsingException {
128
Document doc = new Document(new Element("a"));
129
convertAndCompare(doc);
133
public void testXMLBaseAttributesAreThrownAway()
134
throws SAXException {
136
Element root = new Element("root");
137
Element child = new Element("child");
138
Attribute base = new Attribute("xml:base",
139
"http://www.w3.org/XML/1998/namespace", "data");
140
child.addAttribute(base);
141
root.appendChild(child);
142
Document doc = new Document(root);
143
doc.setBaseURI("http://www.example.com/");
144
converter.setContentHandler(new BaseChecker());
145
converter.convert(doc);
150
private static class BaseChecker extends DefaultHandler {
152
private Locator locator;
154
public void setDocumentLocator(Locator locator) {
155
this.locator = locator;
158
public void startElement(String localName, String qualifiedName,
159
String namespaceURI, Attributes attributes)
160
throws SAXException {
162
if (localName.equals("root")) {
163
assertEquals("http://www.example.com/", locator.getSystemId());
165
else if (localName.equals("child")) {
166
assertEquals("http://www.example.com/data", locator.getSystemId());
169
for (int i=0; i < attributes.getLength(); i++) {
170
String name = attributes.getLocalName(i);
171
String uri = attributes.getURI(i);
172
if ("base".equals(name)
173
&& "http://www.w3.org/XML/1998/namespace".equals(uri)) {
174
fail("Passed xml:base attribute into SAXConverter");
184
public void testDocType()
185
throws IOException, SAXException, ParsingException {
186
Document doc = new Document(new Element("a"));
187
doc.setDocType(new DocType("root"));
188
convertAndCompare(doc);
192
public void testProcessingInstruction()
193
throws IOException, SAXException, ParsingException {
195
Document doc = new Document(new Element("a"));
196
doc.insertChild(new ProcessingInstruction(
197
"xml-stylesheet", "type=\"application/xml\" href=\"stylesheet.xsl\""), 0);
198
convertAndCompare(doc);
203
public void testComment()
204
throws IOException, SAXException, ParsingException {
206
Element root = new Element("root");
207
root.appendChild(" Lots of random text\n\n\n ");
208
Document doc = new Document(root);
209
doc.insertChild(new Comment("some comment data"), 0);
210
root.insertChild(new Comment("some comment data"), 0);
211
doc.appendChild(new Comment("some comment data"));
212
convertAndCompare(doc);
217
public void testDefaultNamespace()
218
throws IOException, SAXException, ParsingException {
219
Document doc = new Document(new Element("a", "http://www.a.com/"));
220
convertAndCompare(doc);
224
public void testTextContent()
225
throws IOException, SAXException, ParsingException {
226
Element root = new Element("root");
227
root.appendChild(" Lots of random text\n\n\n ");
228
Document doc = new Document(root);
229
convertAndCompare(doc);
233
public void testPrefixedNamespace()
234
throws IOException, SAXException, ParsingException {
235
Document doc = new Document(new Element("a:a", "http://www.a.com/"));
236
convertAndCompare(doc);
240
public void testAdditionalNamespace()
241
throws IOException, SAXException, ParsingException {
243
Element root = new Element("root");
244
root.addNamespaceDeclaration("xsl", "http://www.w3.org/1999/XSL/Transform");
245
Document doc = new Document(root);
246
convertAndCompare(doc);
251
public void testPrefixAndAdditionalNamespace()
252
throws IOException, SAXException, ParsingException {
254
Element root = new Element("xsl:root", "http://www.w3.org/1999/XSL/Transform");
255
root.addNamespaceDeclaration("xsl", "http://www.w3.org/1999/XSL/Transform");
256
Document doc = new Document(root);
257
convertAndCompare(doc);
262
public void testPrefixAndAdditionalNamespaceFromParser()
263
throws IOException, SAXException, ParsingException {
264
Document doc = builder.build(
265
"<SOAP:Envelope xmlns:SOAP='http://schemas.xmlsoap.org/soap/envelope/'/>",
267
convertAndCompare(doc);
271
public void testChildElementAddsNamespace()
272
throws IOException, SAXException, ParsingException {
274
Element root = new Element("root");
275
Element child = new Element("pre:child", "http://www.example.org/");
276
child.addAttribute(new Attribute("xlink:type", "http://www.w3.org/1999/xlink", "simple"));
277
root.appendChild(child);
278
Document doc = new Document(root);
279
convertAndCompare(doc);
284
public void testAttributesTypes()
285
throws IOException, SAXException, ParsingException {
287
Element root = new Element("root");
288
root.addAttribute(new Attribute("CDATA", "CDATA", Attribute.Type.CDATA));
289
root.addAttribute(new Attribute("ID", "ID", Attribute.Type.ID));
290
root.addAttribute(new Attribute("IDREF", "IDREF", Attribute.Type.IDREF));
291
root.addAttribute(new Attribute("IDRES", "IDREFS", Attribute.Type.IDREFS));
292
root.addAttribute(new Attribute("NMTOKEN", "NMTOKEN", Attribute.Type.NMTOKEN));
293
root.addAttribute(new Attribute("NMTOKENS", "NMTOKENS", Attribute.Type.NMTOKENS));
294
root.addAttribute(new Attribute("UNDECLARED", "UNDECLARED", Attribute.Type.UNDECLARED));
295
root.addAttribute(new Attribute("ENTITY", "ENTITY", Attribute.Type.ENTITY));
296
root.addAttribute(new Attribute("ENTITIES", "ENTITIES", Attribute.Type.ENTITIES));
297
root.addAttribute(new Attribute("NOTATION", "NOTATION", Attribute.Type.NOTATION));
298
root.addAttribute(new Attribute("ENUMERATION", "ENUMERATION", Attribute.Type.ENUMERATION));
299
Document doc = new Document(root);
300
convertAndCompare(doc);
305
public void testAttributes()
306
throws IOException, SAXException, ParsingException {
308
Element root = new Element("root");
309
root.addAttribute(new Attribute("a", "test"));
310
root.addAttribute(new Attribute("xlink:type",
311
"http://www.w3.org/1999/xlink", "simple"));
312
Document doc = new Document(root);
313
convertAndCompare(doc);
318
public void testExternalDTDSubset()
319
throws IOException, SAXException, ParsingException {
321
File input = new File("data");
322
input = new File(input, "externalDTDtest.xml");
323
Document doc = builder.build(input);
324
convertAndCompare(doc);
329
public void testBigDoc()
330
throws IOException, SAXException, ParsingException {
331
Document doc = builder.build("http://www.cafeconleche.org/");
332
convertAndCompare(doc);
336
public void testNoPrefixMappingEventsForDefaultEmptyNamespace()
337
throws ParsingException, IOException, SAXException {
339
String data = "<root/>";
340
Document doc = builder.build(data, null);
341
ContentHandler handler = new XMLPrefixTester2();
342
SAXConverter converter = new SAXConverter(handler);
343
converter.convert(doc);
348
public void testNoPrefixMappingEventsForXMLPrefix()
349
throws ParsingException, IOException, SAXException {
351
String data = "<root xml:space='preserve'/>";
352
Document doc = builder.build(data, null);
353
ContentHandler handler = new XMLPrefixTester();
354
SAXConverter converter = new SAXConverter(handler);
355
converter.convert(doc);
360
public void testNoPrefixMappingEventsForXMLPrefixOnElement()
361
throws ParsingException, IOException, SAXException {
363
String data = "<xml:root/>";
364
Document doc = builder.build(data, null);
365
ContentHandler handler = new XMLPrefixTester();
366
SAXConverter converter = new SAXConverter(handler);
367
converter.convert(doc);
372
private static class XMLPrefixTester extends DefaultHandler {
374
public void startPrefixMapping(String prefix, String uri) {
375
if ("xml".equals(prefix)) {
376
fail("start mapped prefix xml");
380
public void endPrefixMapping(String prefix) {
381
if ("xml".equals(prefix)) {
382
fail("end mapped prefix xml");
389
private static class XMLPrefixTester2 extends DefaultHandler {
391
public void startPrefixMapping(String prefix, String uri) {
392
fail("start mapped prefix " + prefix);
395
public void endPrefixMapping(String prefix) {
396
fail("end mapped prefix " + prefix);
402
public void testNoRedundantPrefixMappingEventsForDefaultNamespace()
403
throws ParsingException, IOException, SAXException {
405
String data = "<root xmlns='http://www.example.org'> <a> <b/> </a> </root>";
406
Document doc = builder.build(data, null);
407
XMLPrefixMapCounter handler = new XMLPrefixMapCounter();
408
SAXConverter converter = new SAXConverter(handler);
409
converter.convert(doc);
410
assertEquals(1, handler.getStarts());
411
assertEquals(1, handler.getEnds());
416
public void testNoRedundantPrefixMappingEventsForPrefixedNamespace()
417
throws ParsingException, IOException, SAXException {
419
String data = "<a:root xmlns:a='http://www.example.org' />";
420
Document doc = builder.build(data, null);
421
XMLPrefixMapCounter handler = new XMLPrefixMapCounter();
422
SAXConverter converter = new SAXConverter(handler);
423
converter.convert(doc);
424
assertEquals(1, handler.getStarts());
425
assertEquals(1, handler.getEnds());
430
public void testChildNamespace()
431
throws ParsingException, IOException, SAXException {
433
String data = "<a><pre:b xmlns:pre='http://www.example.com'/></a>";
434
Document doc = builder.build(data, null);
435
XMLPrefixMapCounter handler = new XMLPrefixMapCounter();
436
SAXConverter converter = new SAXConverter(handler);
437
converter.convert(doc);
438
assertEquals(1, handler.getStarts());
439
assertEquals(1, handler.getEnds());
444
private static class XMLPrefixMapCounter extends DefaultHandler {
446
private int starts = 0;
447
private int ends = 0;
449
public void startPrefixMapping(String prefix, String uri) {
453
public void endPrefixMapping(String prefix) {