📄 dtdtest.java
字号:
/*
* Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
*
* This software is open source.
* See the bottom of this file for the licence.
*/
package org.dom4j.io;
import junit.framework.AssertionFailedError;
import junit.textui.TestRunner;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.AbstractTestCase;
import org.dom4j.Document;
import org.dom4j.DocumentType;
import org.dom4j.dtd.AttributeDecl;
import org.dom4j.dtd.ElementDecl;
import org.dom4j.dtd.ExternalEntityDecl;
import org.dom4j.dtd.InternalEntityDecl;
import org.dom4j.tree.DefaultDocumentType;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
/**
* Tests the DocType functionality.
*
* <p>
* Incorporated additional test cases for optional processing of the internal
* and external DTD subsets. The "external" and "mixed" tests both <strong>fail
* </strong> due to a reported bug. See http://tinyurl.com/4dzyq
* </p>
*
* @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
* @version $Revision: 1.4 $
*/
public class DTDTest extends AbstractTestCase {
/**
* Input XML file to read <code>xml/dtd/internal.xml</code>- document
* using internal DTD subset, but no external DTD subset.
*/
private static final String XML_INTERNAL_FILE = "xml/dtd/internal.xml";
/**
* Input XML file to read <code>xml/dtd/external.xml</code>- document
* using external DTD subset, but no internal DTD subset. The external
* entity should be locatable by either PUBLIC or SYSTEM identifier. The
* testing harness should use an appropriate EntityResolver to locate the
* external entity as a local resource (no internet access).
*/
private static final String XML_EXTERNAL_FILE = "xml/dtd/external.xml";
/**
* Input XML file to read <code>xml/dtd/mixed.xml</code>- document using
* both an internal and an external DTD subset. The external entity should
* be locatable by either PUBLIC or SYSTEM identifier. The testing harness
* should use an appropriate EntityResolver to locate the external entity as
* a local resource (no internet access).
*/
private static final String XML_MIXED = "xml/dtd/mixed.xml";
/**
* Input XML file to for {@linkEntityResolver}
* <code>xml/dtd/sample.dtd</code>- the external entity providing the
* external DTD subset for test cases that need one. The SYSTEM identifier
* for this external entity is given by {@link#DTD_SYSTEM_ID}.
*/
private static final String DTD_FILE = "xml/dtd/sample.dtd";
/**
* The PUBLIC identifier, which is <code>-//dom4j//DTD sample</code>, for
* the external entity providing DTD for tests.
*/
protected static final String DTD_PUBLICID = "-//dom4j//DTD sample";
/**
* The SYSTEM identifier, which is <code>sample.dtd</code>, for the
* external entity providing DTD for tests.
*/
protected static final String DTD_SYSTEM_ID = "sample.dtd";
public static void main(String[] args) {
TestRunner.run(DTDTest.class);
}
// Test case(s)
// -------------------------------------------------------------------------
/**
* Test verifies correct identification of the internal DTD subset and
* correct non-presence of the external DTD subset.
*
* @throws Exception
* DOCUMENT ME!
*/
public void testInternalDTDSubset() throws Exception {
/*
* Setup the expected DocumentType.
*
* @todo dom4j should expose a DefaultDocumentType constructor that
* accepts only the elementName property. This is used when only an
* internal DTD subset is being provided via the <!DOCTYPE foo [...]>
* syntax, in which case there is neither a SYSTEM nor PUBLIC
* identifier.
*/
DocumentType expected = new DefaultDocumentType();
expected.setElementName("greeting");
expected.setInternalDeclarations(getInternalDeclarations());
/*
* Parse the test XML document and compare the expected and actual
* DOCTYPEs.
*/
try {
assertSameDocumentType(expected, readDocument(
XML_INTERNAL_FILE, true, false).getDocType());
} catch (AssertionFailedError ex) {
throw ex;
} catch (Throwable t) {
fail("Not expecting: " + t);
}
}
/**
* Test verifies correct identification of the external DTD subset and
* correct non-presence of the internal DTD subset.
*/
public void testExternalDTDSubset() {
/*
* Setup the expected DocumentType.
*/
DocumentType expected = new DefaultDocumentType("another-greeting",
null, DTD_SYSTEM_ID);
expected.setExternalDeclarations(getExternalDeclarations());
/*
* Parse the test XML document and compare the expected and actual
* DOCTYPEs.
*/
try {
assertSameDocumentType(expected, readDocument(
XML_EXTERNAL_FILE, false, true).getDocType());
} catch (AssertionFailedError ex) {
throw ex;
} catch (Throwable t) {
fail("Not expecting: " + t);
}
}
/**
* Test verifies correct identification of the internal and external DTD
* subsets.
*/
public void testMixedDTDSubset() {
/*
* Setup the expected DocumentType.
*/
DocumentType expected = new DefaultDocumentType("another-greeting",
null, DTD_SYSTEM_ID);
expected.setInternalDeclarations(getInternalDeclarations());
expected.setExternalDeclarations(getExternalDeclarations());
/*
* Parse the test XML document and compare the expected and actual
* DOCTYPEs.
*/
try {
assertSameDocumentType(expected, readDocument(XML_MIXED,
true, true).getDocType());
} catch (AssertionFailedError ex) {
throw ex;
} catch (Throwable t) {
fail("Not expecting: " + t);
}
}
// Implementation methods
// -------------------------------------------------------------------------
/**
* Test helper method returns a {@link List}of DTD declarations that
* represents the expected internal DTD subset (for the tests that use an
* internal DTD subset).
*
* <p>
* Note: The declarations returned by this method MUST agree those actually
* declared in {@link #XML_INTERNAL_FILE}and {@link
* #XML_MIXED}.
* </p>
*
* <p>
* </p>
*
* @return DOCUMENT ME!
*/
protected List getInternalDeclarations() {
List decls = new ArrayList();
decls.add(new ElementDecl("greeting", "(#PCDATA)"));
decls.add(new AttributeDecl("greeting", "foo", "ID", "#IMPLIED", null));
decls.add(new InternalEntityDecl("%boolean", "( true | false )"));
return decls;
}
/**
* Test helper method returns a {@link List}of DTD declarations that
* represents the expected external DTD subset (for the tests that use an
* external DTD subset).
*
* @return DOCUMENT ME!
*/
protected List getExternalDeclarations() {
List decls = new ArrayList();
decls.add(new ElementDecl("another-greeting", "(#PCDATA)"));
return decls;
}
/**
* Test helper method compares the expected and actual {@link DocumentType}
* objects, including their internal and external DTD subsets.
*
* <p>
* </p>
*
* @param expected
* DOCUMENT ME!
* @param actual
* DOCUMENT ME!
*/
protected void assertSameDocumentType(DocumentType expected,
DocumentType actual) {
/*
* Nothing expected?
*/
if (expected == null) {
if (actual == null) {
return; // Nothing found.
} else {
fail("Not expecting DOCTYPE.");
}
} else {
/*
* Something expected.
*/
if (actual == null) {
fail("Expecting DOCTYPE");
}
log("Expected DocumentType:\n" + expected.toString());
log("Actual DocumentType:\n" + actual.toString());
// Check the internal DTD subset.
assertSameDTDSubset("Internal", expected.getInternalDeclarations(),
actual.getInternalDeclarations());
// Check the external DTD subset.
assertSameDTDSubset("External", expected.getExternalDeclarations(),
actual.getExternalDeclarations());
}
}
/**
* Test helper method compares an expected set of DTD declarations with an
* actual set of DTD declarations. This method should be invoked seperately
* for the internal DTD subset and the external DTD subset. The declarations
* must occur in their logical ordering. See <a
* href="http://tinyurl.com/5jhd8">Lexical Handler </a> for conformance
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -