jstrachan 2002/11/13 11:35:16
Modified: jelly/src/test/org/apache/commons/jelly/xml suite.jelly
jelly/src/java/org/apache/commons/jelly/tags/xml
ElementTag.java
Log:
Patch to fix nesting of <x:element> and <x:attribute> tags as well as new JellyUnit
test cases to test it
Revision Changes Path
1.3 +22 -0
jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/xml/suite.jelly
Index: suite.jelly
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/jelly/src/test/org/apache/commons/jelly/xml/suite.jelly,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- suite.jelly 13 Nov 2002 09:03:31 -0000 1.2
+++ suite.jelly 13 Nov 2002 19:35:14 -0000 1.3
@@ -10,13 +10,35 @@
<x:parse var="doc">
<x:element name="foo">
<x:attribute name="x">1234</x:attribute>
+
+ <x:element name="bar">
+ <x:attribute name="y">ABC</x:attribute>
+ hello
+ </x:element>
</x:element>
</x:parse>
<test:assert xpath="$doc/foo"/>
<test:assert xpath="$doc/foo[@x='1234']"/>
<test:assert xpath="count($doc/bar) = 0"/>
+
+ <!-- test nested element and attributes -->
+ <test:assert xpath="$doc/foo[@x='1234']/bar[@y='ABC']"/>
+ <test:assert xpath="$doc/foo[@x='1234']/bar[@y='ABC']='hello'"/>
+ </test:case>
+
+ <test:case name="testBadElementAndAttribute">
+
+ <j:catch var="ex">
+ <x:element name="foo">
+ some text
+ <x:attribute name="x">1234</x:attribute>
+ </x:element>
+ </j:catch>
+ <test:assert test="${ex != null}">
+ We should have created an exception as some text is output
before the attributes
+ </test:assert>
</test:case>
<test:case name="assertXPathTests">
1.5 +74 -14
jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java
Index: ElementTag.java
===================================================================
RCS file:
/home/cvs/jakarta-commons-sandbox/jelly/src/java/org/apache/commons/jelly/tags/xml/ElementTag.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- ElementTag.java 12 Nov 2002 08:39:50 -0000 1.4
+++ ElementTag.java 13 Nov 2002 19:35:15 -0000 1.5
@@ -67,6 +67,8 @@
import org.apache.commons.jelly.XMLOutput;
import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/** A tag to produce an XML element which can contain other attributes
@@ -86,11 +88,25 @@
/** The XML Attributes */
private AttributesImpl attributes = new AttributesImpl();
+ /** flag set if attributes are output */
+ private boolean outputAttributes;
public ElementTag() {
}
- public void setAttributeValue( String name, String value ) {
+ /**
+ * Sets the attribute of the given name to the specified value.
+ *
* @param name of the attribute
* @param value of the
attribute
* @throws JellyException if the start element has already been
output.
+ * Attributes must be set on the outer element before any content
+ * (child elements or text) is output
*/
+ public void setAttributeValue( String name, String value ) throws
JellyException {
+ if (outputAttributes) {
+ throw new JellyException(
+ "Cannot set the value of attribute: "
+ + name + " as we have already output the startElement() SAX
event"
+ );
+ }
+
// ### we'll assume that all attributes are in no namespace!
// ### this is severely limiting!
// ### we should be namespace aware
@@ -107,22 +123,66 @@
// Tag interface
//-------------------------------------------------------------------------
public void doTag(XMLOutput output) throws Exception {
- String localName = null;
int idx = name.indexOf(':');
- if (idx >= 0) {
- localName = name.substring(idx + 1);
- }
- else {
- localName = name;
- }
+ final String localName = (idx >= 0)
+ ? name.substring(idx + 1)
+ : name;
+
+ outputAttributes = false;
- /**
- * @todo we should buffer up any SAX events and replay then
- * inside the startElement/endElement block
*/
- invokeBody(output);
- output.startElement(namespace, localName, name, attributes);
+ XMLOutput newOutput = new XMLOutput(output) {
+
+ // add an initialize hook to the core content-generating
methods
+
+ public void startElement(
+ String uri,
+ String localName,
+ String qName,
+ Attributes atts)
+ throws SAXException {
+ initialize();
+ super.startElement(uri, localName, qName, atts);
+ }
+
+ public void endElement(String uri, String localName, String qName)
+ throws SAXException {
+ initialize();
+ super.endElement(uri, localName, qName);
+ }
+
+ public void characters(char ch[], int start, int length) throws
SAXException {
+ initialize();
+ super.characters(ch, start, length);
+ }
+
+ public void ignorableWhitespace(char ch[], int start, int length)
+ throws SAXException {
+ initialize();
+ super.ignorableWhitespace(ch, start, length);
+ }
+ public void processingInstruction(String target, String data)
+ throws SAXException {
+ initialize();
+ super.processingInstruction(target, data);
+ }
+
+ /**
+ * Ensure that the outer start element is generated
+ * before any content is output
*/
+ protected void initialize() throws SAXException {
+ if (!outputAttributes) {
+ super.startElement(namespace, localName, name,
attributes);
+ outputAttributes = true;
+ }
+ }
+ };
+
+ invokeBody(newOutput);
- /** @todo we should replay the cached SAX events (if any) here */
+ if (!outputAttributes) {
+ output.startElement(namespace, localName, name, attributes);
+ outputAttributes = true;
+ }
output.endElement(namespace, localName, name);
attributes.clear();
--
To unsubscribe, e-mail: <mailto:commons-dev-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:commons-dev-help@;jakarta.apache.org>