TestElements.java
package org.codehaus.stax.test.stream;
import javax.xml.namespace.*;
import javax.xml.stream.*;
/**
* Unit test suite that tests handling of XML elements, both in namespace
* aware and non-namespace modes.
*
* @author Tatu Saloranta
*/
public class TestElements
extends BaseStreamTest
{
/**
* Method that checks properties of START_ELEMENT and END_ELEMENT
* returned by the stream reader are correct according to StAX specs.
*/
public void testNsProperties()
throws XMLStreamException
{
testProperties(true, "testNsProperties");
}
public void testNonNsProperties()
throws XMLStreamException
{
testProperties(false, "testNonNsProperties");
}
/**
* Does test for simple element structure in namespace aware mode
*/
public void testValidNsElems()
throws XMLStreamException
{
testValid(true, "testValidNsElems");
}
public void testValidNonNsElems()
throws XMLStreamException
{
testValid(false, "testValidNonNsElems");
}
public void testInvalidNsElems()
throws XMLStreamException
{
testInvalid(true, "testInvalidNsElems");
}
public void testInvalidNonNsElems()
throws XMLStreamException
{
testInvalid(false, "testInvalidNonNsElems");
}
public void testEmptyDocument()
throws XMLStreamException
{
String EMPTY_XML = " ";
// Empty documents are not valid (missing root element)
streamThroughFailing(getElemReader(EMPTY_XML, true),
"empty document (not valid, missing root element)");
XMLStreamReader sr = getElemReader(EMPTY_XML, false);
if (sr != null) { // only if non-ns-aware mode supported
streamThroughFailing(sr,
"empty document (not valid, missing root element)");
}
}
public void testNoRootDocument()
throws XMLStreamException
{
String NOROOT_XML = "<?xml version='1.0' ?>\n"
+" <!-- comment...--> <?target !?>";
// Documents without root are not valid
streamThroughFailing(getElemReader(NOROOT_XML, true),
"document without root element");
XMLStreamReader sr = getElemReader(NOROOT_XML, false);
if (sr != null) { // only if non-ns-aware mode supported
streamThroughFailing(sr, "document without root element");
}
}
public void testInvalidEmptyElem()
throws XMLStreamException
{
String XML = "<root> <elem / ></root>";
String MSG = "malformed empty element (space between '/' and '>')";
streamThroughFailing(getElemReader(XML, true), MSG);
XMLStreamReader sr = getElemReader(XML, false);
if (sr != null) { // only if non-ns-aware mode supported
streamThroughFailing(sr, MSG);
}
}
/*
///////////////////////////////////////////////////////////
// Private methods, shared test code
///////////////////////////////////////////////////////////
*/
private void testProperties(boolean nsAware, String method)
throws XMLStreamException
{
XMLStreamReader sr = getElemReader("<root />", nsAware);
if (sr == null) {
reportNADueToNS(method);
return;
}
assertEquals(START_ELEMENT, sr.next());
testStartOrEnd(nsAware, sr, true);
assertEquals(END_ELEMENT, sr.next());
testStartOrEnd(nsAware, sr, false);
}
private void testStartOrEnd(boolean nsAware, XMLStreamReader sr,
boolean isStart)
throws XMLStreamException
{
int evtType = isStart ? START_ELEMENT : END_ELEMENT;
assertEquals(evtType, sr.getEventType());
String eventStr = tokenTypeDesc(evtType);
// simple type info
assertEquals(isStart, sr.isStartElement());
assertEquals(!isStart, sr.isEndElement());
assertEquals(false, sr.isCharacters());
assertEquals(false, sr.isWhiteSpace());
// indirect type info
assertEquals(true, sr.hasName());
assertEquals(false, sr.hasText());
assertNotNull(sr.getLocation());
QName n = sr.getName();
assertNotNull(n);
assertEquals("root", n.getLocalPart());
/* 07-Sep-2007, TSa: The current thinking within Stax community
* is that empty String is the right answer for all unbound
* prefixes and namespace URIs, unless explicitly defined
* that null is to be used for individual methods.
*/
assertEquals("", n.getPrefix());
assertNoNsURI(sr);
if (isStart) {
assertEquals(0, sr.getAttributeCount());
} else {
try {
/*int count =*/ sr.getAttributeCount();
fail("Expected an IllegalStateException when trying to call getAttributeCount() for "+eventStr);
} catch (IllegalStateException e) {
// good
}
}
assertEquals(0, sr.getNamespaceCount());
if (nsAware) {
/* but how about if namespaces are not supported? Can/should
* it return null?
*/
assertNotNull(sr.getNamespaceContext());
}
for (int i = 0; i < 4; ++i) {
String method = "";
try {
@SuppressWarnings("unused")
Object result = null;
switch (i) {
case 0:
method = "getText";
result = sr.getText();
break;
case 1:
method = "getTextCharacters";
result = sr.getTextCharacters();
break;
case 2:
method = "getPITarget";
result = sr.getPITarget();
break;
case 3:
method = "getPIData";
result = sr.getPIData();
break;
}
fail("Expected IllegalStateException, when calling "+method+"() for "+eventStr);
} catch (IllegalStateException iae) {
; // good
}
}
}
private void testValid(boolean nsAware, String method)
throws XMLStreamException
{
final String NS_URL1 = "http://www.stax.org";
final String NS_PREFIX1 = "prefix1";
final String NS_URL2 = "urn://mydummyid";
// final String NS_PREFIX2 = "prefix2";
final String VALID_CONTENT
= "<root><"+NS_PREFIX1+":elem xmlns:"+NS_PREFIX1
+"='"+NS_URL1+"' "+NS_PREFIX1+":attr='value'>Text"
+"</"+NS_PREFIX1+":elem>"
+"<elem2 xmlns='"+NS_URL2+"' attr='value' /></root>";
/* First of all, let's check that it can be completely
* parsed:
*/
XMLStreamReader sr = getElemReader(VALID_CONTENT, nsAware);
if (sr == null) {
reportNADueToNS(method);
return;
}
streamThrough(sr);
// And then let's do it step by step
sr = getElemReader(VALID_CONTENT, nsAware);
// First, need to get <root>
assertTokenType(START_ELEMENT, sr.next());
assertEquals("root", sr.getLocalName());
assertNoPrefix(sr);
assertNoNsURI(sr);
// Let's also check QName seems valid:
QName name = sr.getName();
assertNotNull("Shouldn't get null QName for any start element", name);
assertEquals(name, new QName("root"));
assertNoNsURI(sr);
assertEquals(0, sr.getAttributeCount());
assertEquals(0, sr.getNamespaceCount());
// And then <elem ...>
assertEquals(START_ELEMENT, sr.next());
if (nsAware) {
assertEquals("elem", sr.getLocalName());
assertEquals(NS_PREFIX1, sr.getPrefix());
assertEquals(NS_URL1, sr.getNamespaceURI());
} else {
assertEquals(NS_PREFIX1+":elem", sr.getLocalName());
assertNoPrefix(sr);
assertNoNsURI(sr);
}
int expNs = nsAware ? 1 : 0;
int expAttr = nsAware ? 1 : 2;
/* Let's just check counts, not values; attribute test can
* do thorough tests for values and access
*/
assertEquals(expAttr, sr.getAttributeCount());
assertEquals(expNs, sr.getNamespaceCount());
assertEquals(CHARACTERS, sr.next());
assertEquals("Text", getAndVerifyText(sr));
assertEquals(END_ELEMENT, sr.next());
if (nsAware) {
assertEquals("elem", sr.getLocalName());
assertEquals(NS_PREFIX1, sr.getPrefix());
assertEquals(NS_URL1, sr.getNamespaceURI());
} else {
assertEquals(NS_PREFIX1+":elem", sr.getLocalName());
assertNoPrefix(sr);
assertNoNsURI(sr);
}
assertEquals(expNs, sr.getNamespaceCount());
assertEquals(START_ELEMENT, sr.next());
assertEquals("elem2", sr.getLocalName());
assertNoPrefix(sr);
if (nsAware) {
assertEquals(NS_URL2, sr.getNamespaceURI());
} else {
assertNoNsURI(sr);
}
assertEquals(expAttr, sr.getAttributeCount());
assertEquals(expNs, sr.getNamespaceCount());
assertEquals(END_ELEMENT, sr.next());
assertEquals("elem2", sr.getLocalName());
assertNoPrefix(sr);
if (nsAware) {
assertEquals(NS_URL2, sr.getNamespaceURI());
} else {
assertNoNsURI(sr);
}
assertEquals(expNs, sr.getNamespaceCount());
assertEquals(END_ELEMENT, sr.next());
assertEquals("root", sr.getLocalName());
assertNoNsURI(sr);
assertNoPrefix(sr);
assertEquals(0, sr.getNamespaceCount());
}
/**
* Simple tests to check for incorrect nesting
*/
private void testInvalid(boolean nsAware, String method)
throws XMLStreamException
{
// Wrong end element:
String XML = "<root> text </notroot>";
XMLStreamReader sr = getElemReader(XML, nsAware);
if (sr == null) {
reportNADueToNS(method);
return;
}
streamThroughFailing(sr, "incorrect nesting (wrong end element name)");
// For namespace mode, has to be same prefix (not just same URI)
if (nsAware) {
XML = "<a:root xmlns:a='myurl' xmlns:b='myurl'> text </b:root>";
sr = getElemReader(XML, nsAware);
streamThroughFailing(sr, "incorrect nesting (namespace prefix in close element not the same as in start element)");
}
// Missing end element:
XML = "<root><branch> text </branch>";
streamThroughFailing(getElemReader(XML, nsAware),
"incorrect nesting (missing end element)");
// More than one root:
XML = "<root /><anotherRoot />";
streamThroughFailing(getElemReader(XML, nsAware),
"more than one root element");
}
/*
///////////////////////////////////////////////////////////
// Private methods, other
///////////////////////////////////////////////////////////
*/
private XMLStreamReader getElemReader(String contents, boolean nsAware)
throws XMLStreamException
{
XMLInputFactory f = getInputFactory();
if (!setNamespaceAware(f, nsAware)) {
return null;
}
setCoalescing(f, true);
setValidating(f, false);
return constructStreamReader(f, contents);
}
}