Index: src/main/groovy/xml/MarkupBuilder.java =================================================================== --- src/main/groovy/xml/MarkupBuilder.java (revision 17899) +++ src/main/groovy/xml/MarkupBuilder.java Fri Oct 09 21:29:24 EST 2009 @@ -21,10 +21,13 @@ import java.io.PrintWriter; import java.io.Writer; import java.util.Map; +import java.util.HashMap; +import java.util.Set; +import java.util.Iterator; /** - *
A helper class for creating XML or HTML markup. This implementation outputs - * markup in a 'pretty printed' format.
+ *A helper class for creating XML or HTML markup. + * The builder supports various 'pretty printed' formats.
* *Example:
*new MarkupBuilder().root {
@@ -174,56 +177,40 @@
/**
* Property that may be called from within your builder closure to access
- * helper methods, namely {@link #yield(String)} and
- * {@link #yieldUnescaped(String)}.
+ * helper methods, namely {@link MarkupBuilderHelper#yield(String)},
+ * {@link MarkupBuilderHelper#yieldUnescaped(String)},
+ * {@link MarkupBuilderHelper#pi(Map)},
+ * {@link MarkupBuilderHelper#xmlDeclaration(Map)} and
+ * {@link MarkupBuilderHelper#comment(String)}.
*
* @return this MarkupBuilder
*/
public Object getMkp() {
- return this;
+ return new MarkupBuilderHelper(this);
}
/**
- * Prints data in the body of the current tag, escaping XML entities.
- * For example: mkp.yield('5 < 7')
+ * Produce an XML processing instruction in the output.
+ * For example:
+ *
+ * mkp.pi("xml-stylesheet":[href:"mystyle.css", type:"text/css"])
+ *
*
- * @param value an Object whose toString() representation is to be printed
+ * @param args a map with a single entry whose key is the name of the
+ * processing instruction and whose value is the attributes
+ * for the processing instruction.
*/
- public void yield(Object value) {
- yield(value.toString());
+ void pi(Map> args) {
+ Iterator>> iterator = args.entrySet().iterator();
+ if (iterator.hasNext()) {
+ Map.Entry> mapEntry = iterator.next();
+ createNode("?" + mapEntry.getKey(), mapEntry.getValue());
+ state = 2;
+ out.println("?>");
- }
+ }
-
- /**
- * Prints data in the body of the current tag, escaping XML entities.
- * For example: mkp.yield('5 < 7')
- *
- * @param value text to print
- */
- public void yield(String value) {
- yield(value, true);
}
- /**
- * Print data in the body of the current tag. Does not escape XML entities.
- * For example: mkp.yieldUnescaped('I am <i>happy</i>!').
- *
- * @param value an Object whose toString() representation is to be printed
- */
- public void yieldUnescaped(Object value) {
- yieldUnescaped(value.toString());
- }
-
- /**
- * Print data in the body of the current tag. Does not escape XML entities.
- * For example: mkp.yieldUnescaped('I am <i>happy</i>!').
- *
- * @param value the text or markup to print.
- */
- public void yieldUnescaped(String value) {
- yield(value, false);
- }
-
- private void yield(String value, boolean escaping) {
+ void yield(String value, boolean escaping) {
if (state == 1) {
state = 2;
this.nodeIsEmpty = false;
@@ -275,7 +262,7 @@
}
}
if (value != null) {
- yield(value.toString());
+ yield(value.toString(), true);
} else {
nodeIsEmpty = true;
}
Index: src/main/groovy/xml/MarkupBuilderHelper.java
===================================================================
--- src/main/groovy/xml/MarkupBuilderHelper.java Fri Oct 09 21:29:24 EST 2009
+++ src/main/groovy/xml/MarkupBuilderHelper.java Fri Oct 09 21:29:24 EST 2009
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2003-2009 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package groovy.xml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A helper class for MarkupBuilder.
+ *
+ * @author Paul King
+ */
+public class MarkupBuilderHelper {
+ private MarkupBuilder builder;
+
+ /**
+ * @param builder the builder to delegate to
+ */
+ public MarkupBuilderHelper(MarkupBuilder builder) {
+ this.builder = builder;
+ }
+
+ /**
+ * Prints data in the body of the current tag, escaping XML entities.
+ * For example: mkp.yield('5 < 7')
+ *
+ * @param value an Object whose toString() representation is to be printed
+ */
+ public void yield(Object value) {
+ yield(value.toString());
+ }
+
+ /**
+ * Prints data in the body of the current tag, escaping XML entities.
+ * For example: mkp.yield('5 < 7')
+ *
+ * @param value text to print
+ */
+ public void yield(String value) {
+ builder.yield(value, true);
+ }
+
+ /**
+ * Print data in the body of the current tag. Does not escape XML entities.
+ * For example: mkp.yieldUnescaped('I am <i>happy</i>!').
+ *
+ * @param value an Object whose toString() representation is to be printed
+ */
+ public void yieldUnescaped(Object value) {
+ yieldUnescaped(value.toString());
+ }
+
+ /**
+ * Print data in the body of the current tag. Does not escape XML entities.
+ * For example: mkp.yieldUnescaped('I am <i>happy</i>!').
+ *
+ * @param value the text or markup to print.
+ */
+ public void yieldUnescaped(String value) {
+ builder.yield(value, false);
+ }
+
+ /**
+ * Produce a comment in the output.
+ *
+ * mkp.comment 'string' is equivalent to
+ * mkp.yieldUnescaped '<!-- string -->'.
+ * To create an element with the name 'comment', you need
+ * to supply empty attributes, e.g.:
+ *
+ * comment('hello1')
+ *
+ * or
+ *
+ * mkp.comment('hello1')
+ *
+ * will produce:
+ *
+ * <!-- hello1 -->
+ *
+ * while:
+ *
+ * comment('hello2', [:])
+ *
+ * will produce:
+ *
+ * <comment>hello2</comment>
+ *
+ *
+ * @param value the text within the comment.
+ */
+ public void comment(String value) {
+ yieldUnescaped("");
+ }
+
+ /**
+ * Produce an XML declaration in the output.
+ * For example:
+ *
+ * mkp.xmlDeclaration(version:'1.0')
+ *
+ *
+ * @param args the attributes for the declaration
+ */
+ public void xmlDeclaration(Map args) {
+ Map> map = new HashMap>();
+ map.put("xml", args);
+ pi(map);
+ }
+
+ /**
+ * Produce an XML processing instruction in the output.
+ * For example:
+ *
+ * mkp.pi("xml-stylesheet":[href:"mystyle.css", type:"text/css"])
+ *
+ *
+ * @param args a map with a single entry whose key is the name of the
+ * processing instruction and whose value is the attributes
+ * for the processing instruction.
+ */
+ public void pi(Map> args) {
+ builder.pi(args);
+ }
+
+}
\ No newline at end of file
Index: src/test/groovy/xml/MarkupBuilderTest.groovy
===================================================================
--- src/test/groovy/xml/MarkupBuilderTest.groovy (revision 17903)
+++ src/test/groovy/xml/MarkupBuilderTest.groovy Fri Oct 09 21:33:41 EST 2009
@@ -37,20 +37,6 @@
checkXml expectedXml, writer
}
- void testSmallTree() {
- xml.root1(a:5, b:7) {
- elem1('hello1')
- elem2('hello2')
- elem3(x:7)
- }
- assertExpectedXml '''\
-
- hello1
- hello2
-
- '''
- }
-
/**
* It is not recommended practice to use the value attribute
* when also using nested content as there is no way to specify
@@ -246,18 +232,6 @@
assert writer.toString() == "foo "
}
- void testMarkupBuilderAllowsMkpToBeDropped() {
- def m = {
- p {
- yield 'Red: Hearts & Diamonds'
- br()
- yieldUnescaped 'Black: Spades & Clubs'
- }
- }
- assertExpectedXml m, '''\
-Red: Hearts & Diamonds\n
Black: Spades & Clubs \n
'''
- }
-
private myMethod(x) {
x.value='call to outside'
return x
Index: src/test/groovy/xml/StreamingMarkupBuilderTest.groovy
===================================================================
--- src/test/groovy/xml/StreamingMarkupBuilderTest.groovy (revision 17903)
+++ src/test/groovy/xml/StreamingMarkupBuilderTest.groovy Wed Oct 07 21:25:26 EST 2009
@@ -32,29 +32,4 @@
checkXml(expectedXml, writer)
}
- /**
- * test some StreamingMarkupBuilder specific mkp functionality
- */
- void testSmallTree() {
- def m = {
- mkp.xmlDeclaration(version:'1.0')
- mkp.pi("xml-stylesheet":[href:"mystyle.css", type:"text/css"])
- root1(a:5, b:7) {
- elem1('hello1')
- elem2('hello2')
- mkp.comment('hello3')
- elem3(x:7)
- }
+}
\ No newline at end of file
- }
- assertExpectedXml m, '''\
-
-
-
- hello1
- hello2
-
-
- '''
- }
-
-}
\ No newline at end of file
Index: src/test/groovy/xml/BuilderTestSupport.groovy
===================================================================
--- src/test/groovy/xml/BuilderTestSupport.groovy (revision 17903)
+++ src/test/groovy/xml/BuilderTestSupport.groovy Fri Oct 09 21:12:01 EST 2009
@@ -32,7 +32,7 @@
protected checkXml(String expectedXml, StringWriter writer) {
XMLUnit.ignoreWhitespace = true
def xmlDiff = new Diff(expectedXml, writer.toString())
- assert xmlDiff.similar(), xmlDiff.toString()
+ assert xmlDiff.similar(), xmlDiff.toString() + "\n" + writer.toString()
}
void testHref() {
@@ -197,13 +197,44 @@
* yield and yieldUnescaped should call toString() if a non-String object is passed as argument
*/
void testYieldObjectToStringRepresentation() {
- def out = new StringWriter()
- new MarkupBuilder(out).table {
+ def m = {
+ table {
- td(id: 999) { mkp.yield 999 }
- td(id: 99) { mkp.yieldUnescaped 99 }
- }
+ td(id: 999) { mkp.yield 999 }
+ td(id: 99) { mkp.yieldUnescaped 99 }
+ }
+ }
+ assertExpectedXml m, "999 99
"
+ }
- assert !out.toString().contains('yield')
+ /**
+ * test special builder mkp functionality
+ */
+ void testSmallTreeWithMkpFunctionality() {
+ def m = {
+ mkp.xmlDeclaration(version: '1.0')
+ mkp.pi("xml-stylesheet": [href: "mystyle.css", type: "text/css"])
+ root1(a: 5, b: 7) {
+ elem1('hello1')
+ elem2('hello2')
+ mkp.comment('hello3')
+ comment('hello4', [:])
+ comment(value: 'hello5')
+ comment {}
+ elem3(x: 7)
- }
+ }
+ }
+ assertExpectedXml m, '''\
+
+
+
+ hello1
+ hello2
+
+ hello4
+
+
+
+ '''
+ }
}
\ No newline at end of file