You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/05/21 21:34:57 UTC
[2/6] incubator-freemarker git commit: Factored out freemarker-dom
from freemarker-core. Also added mechanism to "inject" DOM wrapping
capability into DefaultObjectWrapper on configuration time. See details
below.
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/main/java/org/apache/freemarker/dom/package.html
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/main/java/org/apache/freemarker/dom/package.html b/freemarker-dom/src/main/java/org/apache/freemarker/dom/package.html
new file mode 100644
index 0000000..61b1737
--- /dev/null
+++ b/freemarker-dom/src/main/java/org/apache/freemarker/dom/package.html
@@ -0,0 +1,30 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<html>
+<head>
+<title></title>
+</head>
+<body>
+
+<p>Exposes DOM XML nodes to templates as easily traversable trees;
+see <a href="http://freemarker.org/docs/xgui.html" target="_blank">in the Manual</a>.
+The default object wrapper of FreeMarker can automatically wraps W3C nodes with this.
+
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
new file mode 100644
index 0000000..ed6d7bb
--- /dev/null
+++ b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSiblingTest.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.freemarker.dom;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.dom.test.DOMLoader;
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+public class DOMSiblingTest extends TemplateTest {
+
+ @Before
+ public void setUp() throws SAXException, IOException, ParserConfigurationException {
+ addToDataModel("doc", DOMLoader.toModel(getClass(),"DOMSiblingTest.xml"));
+ }
+
+ @Test
+ public void testBlankPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.name?previousSibling}", "\n ");
+ assertOutput("${doc.person.name?previous_sibling}", "\n ");
+ }
+
+ @Test
+ public void testNonBlankPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.address?previousSibling}", "12th August");
+ }
+
+ @Test
+ public void testBlankNextSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.name?nextSibling}", "\n ");
+ assertOutput("${doc.person.name?next_sibling}", "\n ");
+ }
+
+ @Test
+ public void testNonBlankNextSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.dob?nextSibling}", "Chennai, India");
+ }
+
+ @Test
+ public void testNullPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person?previousSibling?? ?c}", "false");
+ }
+
+ @Test
+ public void testSignificantPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.name.@@previous_sibling_element}", "male");
+ }
+
+ @Test
+ public void testSignificantNextSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.name.@@next_sibling_element}", "12th August");
+ }
+
+ @Test
+ public void testNullSignificantPreviousSibling() throws IOException, TemplateException {
+ assertOutput("${doc.person.phone.@@next_sibling_element?size}", "0");
+ }
+
+ @Test
+ public void testSkippingCommentNode() throws IOException, TemplateException {
+ assertOutput("${doc.person.profession.@@previous_sibling_element}", "Chennai, India");
+ }
+
+ @Test
+ public void testSkippingEmptyCDataNode() throws IOException, TemplateException {
+ assertOutput("${doc.person.hobby.@@previous_sibling_element}", "Software Engineer");
+ }
+
+ @Test
+ public void testValidCDataNode() throws IOException, TemplateException {
+ assertOutput("${doc.person.phone.@@previous_sibling_element?size}", "0");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java
new file mode 100644
index 0000000..d8004fb
--- /dev/null
+++ b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMSimplifiersTest.java
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.freemarker.dom;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.dom.test.DOMLoader;
+import org.junit.Test;
+import org.w3c.dom.CDATASection;
+import org.w3c.dom.Comment;
+import org.w3c.dom.Document;
+import org.w3c.dom.DocumentType;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.ProcessingInstruction;
+import org.w3c.dom.Text;
+import org.xml.sax.SAXException;
+
+public class DOMSimplifiersTest {
+
+ private static final String COMMON_TEST_XML
+ = "<!DOCTYPE a []><?p?><a>x<![CDATA[y]]><!--c--><?p?>z<?p?><b><!--c--></b><c></c>"
+ + "<d>a<e>c</e>b<!--c--><!--c--><!--c--><?p?><?p?><?p?></d>"
+ + "<f><![CDATA[1]]>2</f></a><!--c-->";
+
+ private static final String TEXT_MERGE_CONTENT =
+ "<a>"
+ + "a<!--c--><s/>"
+ + "<!--c-->a<s/>"
+ + "a<!--c-->b<s/>"
+ + "<!--c-->a<!--c-->b<!--c--><s/>"
+ + "a<b>b</b>c<s/>"
+ + "a<b>b</b><!--c-->c<s/>"
+ + "a<!--c-->1<b>b<!--c--></b>c<!--c-->1<s/>"
+ + "a<!--c-->1<b>b<!--c-->c</b>d<!--c-->1<s/>"
+ + "a<!--c-->1<b>b<!--c-->c</b>d<!--c-->1<s/>"
+ + "a<!--c-->1<b>b<!--c-->1<e>c<!--c-->1</e>d<!--c-->1</b>e<!--c-->1<s/>"
+ + "</a>";
+ private static final String TEXT_MERGE_EXPECTED =
+ "<a>"
+ + "%a<s/>"
+ + "%a<s/>"
+ + "%ab<s/>"
+ + "%ab<s/>"
+ + "%a<b>%b</b>%c<s/>"
+ + "%a<b>%b</b>%c<s/>"
+ + "%a1<b>%b</b>%c1<s/>"
+ + "%a1<b>%bc</b>%d1<s/>"
+ + "%a1<b>%bc</b>%d1<s/>"
+ + "%a1<b>%b1<e>%c1</e>%d1</b>%e1<s/>"
+ + "</a>";
+
+ @Test
+ public void testTest() throws Exception {
+ String expected = "<!DOCTYPE ...><?p?><a>%x<![CDATA[y]]><!--c--><?p?>%z<?p?><b><!--c--></b><c/>"
+ + "<d>%a<e>%c</e>%b<!--c--><!--c--><!--c--><?p?><?p?><?p?></d>"
+ + "<f><![CDATA[1]]>%2</f></a><!--c-->";
+ assertEquals(expected, toString(DOMLoader.toDOM(COMMON_TEST_XML)));
+ }
+
+ @Test
+ public void testMergeAdjacentText() throws Exception {
+ Document dom = DOMLoader.toDOM(COMMON_TEST_XML);
+ NodeModel.mergeAdjacentText(dom);
+ assertEquals(
+ "<!DOCTYPE ...><?p?><a>%xy<!--c--><?p?>%z<?p?><b><!--c--></b><c/>"
+ + "<d>%a<e>%c</e>%b<!--c--><!--c--><!--c--><?p?><?p?><?p?></d>"
+ + "<f><![CDATA[12]]></f></a><!--c-->",
+ toString(dom));
+ }
+
+ @Test
+ public void testRemoveComments() throws Exception {
+ Document dom = DOMLoader.toDOM(COMMON_TEST_XML);
+ NodeModel.removeComments(dom);
+ assertEquals(
+ "<!DOCTYPE ...><?p?><a>%x<![CDATA[y]]><?p?>%z<?p?><b/><c/>"
+ + "<d>%a<e>%c</e>%b<?p?><?p?><?p?></d>"
+ + "<f><![CDATA[1]]>%2</f></a>",
+ toString(dom));
+ }
+
+ @Test
+ public void testRemovePIs() throws Exception {
+ Document dom = DOMLoader.toDOM(COMMON_TEST_XML);
+ NodeModel.removePIs(dom);
+ assertEquals(
+ "<!DOCTYPE ...><a>%x<![CDATA[y]]><!--c-->%z<b><!--c--></b><c/>"
+ + "<d>%a<e>%c</e>%b<!--c--><!--c--><!--c--></d>"
+ + "<f><![CDATA[1]]>%2</f></a><!--c-->",
+ toString(dom));
+ }
+
+ @Test
+ public void testSimplify() throws Exception {
+ testSimplify(
+ "<!DOCTYPE ...><a>%xyz<b/><c/>"
+ + "<d>%a<e>%c</e>%b</d><f><![CDATA[12]]></f></a>",
+ COMMON_TEST_XML);
+ }
+
+ @Test
+ public void testSimplify2() throws Exception {
+ testSimplify(TEXT_MERGE_EXPECTED, TEXT_MERGE_CONTENT);
+ }
+
+ @Test
+ public void testSimplify3() throws Exception {
+ testSimplify("<a/>", "<a/>");
+ }
+
+ private void testSimplify(String expected, String content)
+ throws SAXException, IOException, ParserConfigurationException {
+ {
+ Document dom = DOMLoader.toDOM(content);
+ NodeModel.simplify(dom);
+ assertEquals(expected, toString(dom));
+ }
+
+ // Must be equivalent:
+ {
+ Document dom = DOMLoader.toDOM(content);
+ NodeModel.removeComments(dom);
+ NodeModel.removePIs(dom);
+ NodeModel.mergeAdjacentText(dom);
+ assertEquals(expected, toString(dom));
+ }
+
+ // Must be equivalent:
+ {
+ Document dom = DOMLoader.toDOM(content);
+ NodeModel.removeComments(dom);
+ NodeModel.removePIs(dom);
+ NodeModel.simplify(dom);
+ assertEquals(expected, toString(dom));
+ }
+ }
+
+ private String toString(Document doc) {
+ StringBuilder sb = new StringBuilder();
+ toString(doc, sb);
+ return sb.toString();
+ }
+
+ private void toString(Node node, StringBuilder sb) {
+ if (node instanceof Document) {
+ childrenToString(node, sb);
+ } else if (node instanceof Element) {
+ if (node.hasChildNodes()) {
+ sb.append("<").append(node.getNodeName()).append(">");
+ childrenToString(node, sb);
+ sb.append("</").append(node.getNodeName()).append(">");
+ } else {
+ sb.append("<").append(node.getNodeName()).append("/>");
+ }
+ } else if (node instanceof Text) {
+ if (node instanceof CDATASection) {
+ sb.append("<![CDATA[").append(node.getNodeValue()).append("]]>");
+ } else {
+ sb.append("%").append(node.getNodeValue());
+ }
+ } else if (node instanceof Comment) {
+ sb.append("<!--").append(node.getNodeValue()).append("-->");
+ } else if (node instanceof ProcessingInstruction) {
+ sb.append("<?").append(node.getNodeName()).append("?>");
+ } else if (node instanceof DocumentType) {
+ sb.append("<!DOCTYPE ...>");
+ } else {
+ throw new IllegalStateException("Unhandled node type: " + node.getClass().getName());
+ }
+ }
+
+ private void childrenToString(Node node, StringBuilder sb) {
+ Node child = node.getFirstChild();
+ while (child != null) {
+ toString(child, sb);
+ child = child.getNextSibling();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMTest.java
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMTest.java b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMTest.java
new file mode 100644
index 0000000..0d03dbe
--- /dev/null
+++ b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DOMTest.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.freemarker.dom;
+
+import static org.hamcrest.Matchers.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringReader;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.dom.test.DOMLoader;
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class DOMTest extends TemplateTest {
+
+ @Test
+ public void xpathDetectionBugfix() throws Exception {
+ addDocToDataModel("<root><a>A</a><b>B</b><c>C</c></root>");
+ assertOutput("${doc.root.b['following-sibling::c']}", "C");
+ assertOutput("${doc.root.b['following-sibling::*']}", "C");
+ }
+
+ @Test
+ public void xmlnsPrefixes() throws Exception {
+ addDocToDataModel("<root xmlns='http://example.com/ns1' xmlns:ns2='http://example.com/ns2'>"
+ + "<a>A</a><ns2:b>B</ns2:b><c a1='1' ns2:a2='2'/></root>");
+
+ String ftlHeader = "<#ftl ns_prefixes={'D':'http://example.com/ns1', 'n2':'http://example.com/ns2'}>";
+
+ // @@markup:
+ assertOutput("${doc.@@markup}",
+ "<a:root xmlns:a=\"http://example.com/ns1\" xmlns:b=\"http://example.com/ns2\">"
+ + "<a:a>A</a:a><b:b>B</b:b><a:c a1=\"1\" b:a2=\"2\" />"
+ + "</a:root>");
+ assertOutput(ftlHeader
+ + "${doc.@@markup}",
+ "<root xmlns=\"http://example.com/ns1\" xmlns:n2=\"http://example.com/ns2\">"
+ + "<a>A</a><n2:b>B</n2:b><c a1=\"1\" n2:a2=\"2\" /></root>");
+ assertOutput("<#ftl ns_prefixes={'D':'http://example.com/ns1'}>"
+ + "${doc.@@markup}",
+ "<root xmlns=\"http://example.com/ns1\" xmlns:a=\"http://example.com/ns2\">"
+ + "<a>A</a><a:b>B</a:b><c a1=\"1\" a:a2=\"2\" /></root>");
+
+ // When there's no matching prefix declared via the #ftl header, return null for qname:
+ assertOutput("${doc?children[0].@@qname!'null'}", "null");
+ assertOutput("${doc?children[0]?children[1].@@qname!'null'}", "null");
+ assertOutput("${doc?children[0]?children[2]['@*'][1].@@qname!'null'}", "null");
+
+ // When we have prefix declared in the #ftl header:
+ assertOutput(ftlHeader + "${doc?children[0].@@qname}", "root");
+ assertOutput(ftlHeader + "${doc?children[0]?children[1].@@qname}", "n2:b");
+ assertOutput(ftlHeader + "${doc?children[0]?children[2].@@qname}", "c");
+ assertOutput(ftlHeader + "${doc?children[0]?children[2]['@*'][0].@@qname}", "a1");
+ assertOutput(ftlHeader + "${doc?children[0]?children[2]['@*'][1].@@qname}", "n2:a2");
+ // Unfortunately these include the xmlns attributes, but that would be non-BC to fix now:
+ assertThat(getOutput(ftlHeader + "${doc?children[0].@@start_tag}"), startsWith("<root"));
+ assertThat(getOutput(ftlHeader + "${doc?children[0]?children[1].@@start_tag}"), startsWith("<n2:b"));
+ }
+
+ @Test
+ public void namespaceUnaware() throws Exception {
+ addNSUnawareDocToDataModel("<root><x:a>A</x:a><:>B</:><xyz::c>C</xyz::c></root>");
+ assertOutput("${doc.root['x:a']}", "A");
+ assertOutput("${doc.root[':']}", "B");
+ try {
+ assertOutput("${doc.root['xyz::c']}", "C");
+ fail();
+ } catch (TemplateException e) {
+ assertThat(e.getMessage(), containsString("xyz"));
+ }
+ }
+
+ private void addDocToDataModel(String xml) throws SAXException, IOException, ParserConfigurationException {
+ addToDataModel("doc", DOMLoader.toModel(new InputSource(new StringReader(xml))));
+ }
+
+ private void addDocToDataModelNoSimplification(String xml) throws SAXException, IOException, ParserConfigurationException {
+ addToDataModel("doc", DOMLoader.toModel(new InputSource(new StringReader(xml)), false));
+ }
+
+ private void addNSUnawareDocToDataModel(String xml) throws ParserConfigurationException, SAXException, IOException {
+ DocumentBuilderFactory newFactory = DocumentBuilderFactory.newInstance();
+ newFactory.setNamespaceAware(false);
+ DocumentBuilder builder = newFactory.newDocumentBuilder();
+ Document doc = builder.parse(new InputSource(new StringReader(xml)));
+ addToDataModel("doc", NodeModel.wrap(doc));
+ }
+
+ @Test
+ public void testInvalidAtAtKeyErrors() throws Exception {
+ addDocToDataModel("<r><multipleMatches /><multipleMatches /></r>");
+ assertErrorContains("${doc.r.@@invalid_key}", "Unsupported @@ key", "@invalid_key");
+ assertErrorContains("${doc.@@start_tag}", "@@start_tag", "not supported", "document");
+ assertErrorContains("${doc.@@}", "\"@@\"", "not supported", "document");
+ assertErrorContains("${doc.r.noMatch.@@invalid_key}", "Unsupported @@ key", "@invalid_key");
+ assertErrorContains("${doc.r.multipleMatches.@@invalid_key}", "Unsupported @@ key", "@invalid_key");
+ assertErrorContains("${doc.r.noMatch.@@attributes_markup}", "single XML node", "@@attributes_markup");
+ assertErrorContains("${doc.r.multipleMatches.@@attributes_markup}", "single XML node", "@@attributes_markup");
+ }
+
+ @Test
+ public void testAtAtSiblingElement() throws Exception {
+ addDocToDataModel("<r><a/><b/></r>");
+ assertOutput("${doc.r.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.@@next_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
+ assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
+ assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
+
+ addDocToDataModel("<r>\r\n\t <a/>\r\n\t <b/>\r\n\t </r>");
+ assertOutput("${doc.r.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.@@next_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
+ assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
+ assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
+
+ addDocToDataModel("<r>t<a/>t<b/>t</r>");
+ assertOutput("${doc.r.a.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.a.@@next_sibling_element?size}", "0");
+ assertOutput("${doc.r.b.@@previous_sibling_element?size}", "0");
+ assertOutput("${doc.r.b.@@next_sibling_element?size}", "0");
+
+ addDocToDataModelNoSimplification("<r><a/> <!-- --><?pi?> <b/></r>");
+ assertOutput("${doc.r.a.@@next_sibling_element.@@qname}", "b");
+ assertOutput("${doc.r.b.@@previous_sibling_element.@@qname}", "a");
+
+ addDocToDataModelNoSimplification("<r><a/> <!-- -->t<!-- --> <b/></r>");
+ assertOutput("${doc.r.a.@@next_sibling_element?size}", "0");
+ assertOutput("${doc.r.b.@@previous_sibling_element?size}", "0");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/java/org/apache/freemarker/dom/DefaultObjectWrapperExtensionTest.java
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/java/org/apache/freemarker/dom/DefaultObjectWrapperExtensionTest.java b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DefaultObjectWrapperExtensionTest.java
new file mode 100644
index 0000000..347980d
--- /dev/null
+++ b/freemarker-dom/src/test/java/org/apache/freemarker/dom/DefaultObjectWrapperExtensionTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.freemarker.dom;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.core.TemplateException;
+import org.apache.freemarker.core.model.impl.DefaultObjectWrapper;
+import org.apache.freemarker.dom.test.DOMLoader;
+import org.apache.freemarker.test.TemplateTest;
+import org.apache.freemarker.test.TestConfigurationBuilder;
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.SAXException;
+
+public class DefaultObjectWrapperExtensionTest extends TemplateTest {
+
+ @Before
+ public void setup() throws ParserConfigurationException, SAXException, IOException {
+ addToDataModel("doc", DOMLoader.toDOM("<doc><title>test</title></doc>").getDocumentElement());
+ }
+
+ @Test
+ public void testWithExtensions() throws IOException, TemplateException {
+ setConfiguration(new TestConfigurationBuilder()
+ .objectWrapper(
+ new DefaultObjectWrapper.Builder(Configuration.VERSION_3_0_0)
+ .extensions(DOMDefaultObjectWrapperExtension.INSTANCE)
+ .build()
+ )
+ .build());
+ assertOutput("${doc.title}", "test");
+ }
+
+ @Test
+ public void testWithoutExtensions() throws IOException, TemplateException {
+ try {
+ assertOutput("${doc.title}", "test");
+ fail();
+ } catch (TemplateException e) {
+ // Expected
+ }
+
+ assertOutput("${doc.getElementsByTagName('title').item(0).textContent}", "test");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/java/org/apache/freemarker/dom/TypeErrorMessagesTest.java
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/java/org/apache/freemarker/dom/TypeErrorMessagesTest.java b/freemarker-dom/src/test/java/org/apache/freemarker/dom/TypeErrorMessagesTest.java
new file mode 100644
index 0000000..b2f1304
--- /dev/null
+++ b/freemarker-dom/src/test/java/org/apache/freemarker/dom/TypeErrorMessagesTest.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.freemarker.dom;
+
+import org.apache.freemarker.dom.test.DOMLoader;
+import org.apache.freemarker.test.TemplateTest;
+import org.junit.Test;
+
+public class TypeErrorMessagesTest extends TemplateTest {
+
+ @Test
+ public void test() throws Exception {
+ addToDataModel("doc", DOMLoader.toModel("<a><b>123</b><c a='true'>1</c><c a='false'>2</c></a>"));
+
+ assertErrorContains("${doc.a.c}",
+ "used as string", "query result", "2", "multiple matches");
+ assertErrorContains("${doc.a.c?boolean}",
+ "used as string", "query result", "2", "multiple matches");
+ assertErrorContains("${doc.a.d}",
+ "used as string", "query result", "0", "no matches");
+ assertErrorContains("${doc.a.d?boolean}",
+ "used as string", "query result", "0", "no matches");
+
+ assertErrorContains("${doc.a.c.@a}",
+ "used as string", "query result", "2", "multiple matches");
+ assertErrorContains("${doc.a.d.@b}",
+ "used as string", "query result", "x", "no matches");
+
+ assertErrorContains("${doc.a.b * 2}",
+ "used as number", "text", "explicit conversion");
+ assertErrorContains("<#if doc.a.b></#if>",
+ "used as number", "text", "explicit conversion");
+
+ assertErrorContains("${doc.a.d?nodeName}",
+ "used as node", "query result", "0", "no matches");
+ assertErrorContains("${doc.a.c?nodeName}",
+ "used as node", "query result", "2", "multiple matches");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/java/org/apache/freemarker/dom/templatesuite/DomTemplateTestSuite.java
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/java/org/apache/freemarker/dom/templatesuite/DomTemplateTestSuite.java b/freemarker-dom/src/test/java/org/apache/freemarker/dom/templatesuite/DomTemplateTestSuite.java
new file mode 100644
index 0000000..e3a91e1
--- /dev/null
+++ b/freemarker-dom/src/test/java/org/apache/freemarker/dom/templatesuite/DomTemplateTestSuite.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.freemarker.dom.templatesuite;
+
+import java.util.Map;
+
+import org.apache.freemarker.core.Configuration;
+import org.apache.freemarker.dom.NodeModel;
+import org.apache.freemarker.dom.test.DOMLoader;
+import org.apache.freemarker.test.TemplateTestSuite;
+import org.w3c.dom.Document;
+
+import junit.framework.TestSuite;
+
+public class DomTemplateTestSuite extends TemplateTestSuite {
+
+ @Override
+ protected void setUpTestCase(String simpleTestName, Map<String, Object> dataModel,
+ Configuration.ExtendableBuilder<?> confB) throws Exception {
+ NodeModel.useJaxenXPathSupport();
+
+ if (simpleTestName.equals("default-xmlns")) {
+ dataModel.put("doc", DOMLoader.toModel(getClass(), "models/defaultxmlns1.xml"));
+ } else if (simpleTestName.equals("xml-fragment")) {
+ Document doc = DOMLoader.toDOM(getClass(), "models/xmlfragment.xml");
+ NodeModel.simplify(doc);
+ dataModel.put("node", NodeModel.wrap(doc.getDocumentElement().getFirstChild().getFirstChild()));
+ } else if (simpleTestName.equals("xmlns1")) {
+ dataModel.put("doc", DOMLoader.toModel(getClass(), "models/xmlns.xml"));
+ } else if (simpleTestName.equals("xmlns2")) {
+ dataModel.put("doc", DOMLoader.toModel(getClass(), "models/xmlns2.xml"));
+ } else if (simpleTestName.equals("xmlns3") || simpleTestName.equals("xmlns4")) {
+ dataModel.put("doc", DOMLoader.toModel(getClass(), "models/xmlns3.xml"));
+ } else if (simpleTestName.equals("xmlns5")) {
+ dataModel.put("doc", DOMLoader.toModel(getClass(), "models/defaultxmlns1.xml"));
+ } else if (simpleTestName.equals("xml-ns_prefix-scope")) {
+ dataModel.put("doc", DOMLoader.toModel(getClass(), "models/xml-ns_prefix-scope.xml"));
+ }
+ }
+
+ public static TestSuite suite() {
+ return new DomTemplateTestSuite();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/java/org/apache/freemarker/dom/test/DOMLoader.java
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/java/org/apache/freemarker/dom/test/DOMLoader.java b/freemarker-dom/src/test/java/org/apache/freemarker/dom/test/DOMLoader.java
new file mode 100644
index 0000000..bc957c5
--- /dev/null
+++ b/freemarker-dom/src/test/java/org/apache/freemarker/dom/test/DOMLoader.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.freemarker.dom.test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.net.MalformedURLException;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.freemarker.core.util._StringUtil;
+import org.apache.freemarker.dom.NodeModel;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Utility to load XML resources into {@link Node}-s or {@link NodeModel}-s.
+ */
+public final class DOMLoader {
+
+ private static final Object STATIC_LOCK = new Object();
+
+ static private DocumentBuilderFactory docBuilderFactory;
+
+ private DOMLoader() {
+ //
+ }
+
+ /**
+ * Convenience method to invoke a {@link NodeModel} from a SAX {@link InputSource}.
+ */
+ static public NodeModel toModel(InputSource is, boolean simplify)
+ throws SAXException, IOException, ParserConfigurationException {
+ DocumentBuilder builder = getDocumentBuilderFactory().newDocumentBuilder();
+ final Document doc;
+ try {
+ doc = builder.parse(is);
+ } catch (MalformedURLException e) {
+ // This typical error has an error message that is hard to understand, so let's translate it:
+ if (is.getSystemId() == null && is.getCharacterStream() == null && is.getByteStream() == null) {
+ throw new MalformedURLException(
+ "The SAX InputSource has systemId == null && characterStream == null && byteStream == null. "
+ + "This is often because it was created with a null InputStream or Reader, which is often because "
+ + "the XML file it should point to was not found. "
+ + "(The original exception was: " + e + ")");
+ } else {
+ throw e;
+ }
+ }
+ if (simplify) {
+ NodeModel.simplify(doc);
+ }
+ return NodeModel.wrap(doc);
+ }
+
+ /**
+ * Same as {@link #toModel(InputSource, boolean) parse(is, true)}.
+ */
+ static public NodeModel toModel(InputSource is) throws SAXException, IOException, ParserConfigurationException {
+ return toModel(is, true);
+ }
+
+ static public NodeModel toModel(Class<?> baseClass, String resourcePath)
+ throws ParserConfigurationException, SAXException, IOException {
+ InputStream in = baseClass.getResourceAsStream(resourcePath);
+ if (in == null) {
+ throw new FileNotFoundException("Class loader resource not found: baseClass=" + baseClass.getName()
+ + "; path=" + _StringUtil.jQuote(resourcePath));
+ }
+ return toModel(new InputSource(in));
+ }
+
+ /**
+ * Same as {@link #toModel(InputSource, boolean)}, but loads from a {@link File}; don't miss the security
+ * warnings documented there.
+ */
+ static public NodeModel toModel(String content, boolean simplify)
+ throws SAXException, IOException, ParserConfigurationException {
+ return toModel(toInputSource(content));
+ }
+
+ /**
+ * Same as {@link #toModel(InputSource, boolean) parse(source, true)}, but loads from a {@link String}.
+ */
+ static public NodeModel toModel(String content) throws SAXException, IOException, ParserConfigurationException {
+ return toModel(content, true);
+ }
+
+ public static Document toDOM(String content) throws SAXException, IOException, ParserConfigurationException {
+ DocumentBuilder builder = getDocumentBuilderFactory().newDocumentBuilder();
+ return builder.parse(toInputSource(content));
+ }
+
+ public static Document toDOM(Class<?> baseClass, String resourcePath) throws SAXException, IOException,
+ ParserConfigurationException {
+ DocumentBuilder builder = getDocumentBuilderFactory().newDocumentBuilder();
+ InputStream in = baseClass.getResourceAsStream(resourcePath);
+ if (in == null) {
+ throw new FileNotFoundException("Class loader resource not found: baseClass="
+ + baseClass.getName() + "; " + "path=" + _StringUtil.jQuote(resourcePath));
+ }
+ return builder.parse(new InputSource(in));
+ }
+
+ static private DocumentBuilderFactory getDocumentBuilderFactory() {
+ synchronized (STATIC_LOCK) {
+ if (docBuilderFactory == null) {
+ DocumentBuilderFactory newFactory = DocumentBuilderFactory.newInstance();
+ newFactory.setNamespaceAware(true);
+ newFactory.setIgnoringElementContentWhitespace(true);
+ docBuilderFactory = newFactory; // We only write it out when the initialization was full
+ }
+ return docBuilderFactory;
+ }
+ }
+
+ private static InputSource toInputSource(String content) {
+ return new InputSource(new StringReader(content));
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml
new file mode 100644
index 0000000..d1fe3dc
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/DOMSiblingTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<person>
+ <gender>male</gender>
+ <name>pradeep</name>
+ <dob>12th August</dob><address>Chennai, India</address>
+ <!--This is a comment Node -->
+ <?xml-stylesheet type="text/css" href="style.css"?>
+ <profession>Software Engineer</profession>
+ <![CDATA[ ]]>
+ <hobby>gardening</hobby>
+ <![CDATA[this is a valid cdata]]>
+ <phone>12345678</phone>
+</person>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/default-xmlns.txt
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/default-xmlns.txt b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/default-xmlns.txt
new file mode 100644
index 0000000..3a52c46
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/default-xmlns.txt
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+No NS = No NS
+x NS = x NS
+y NS = y NS
+x NS = x NS
+
+true
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml-fragment.txt
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml-fragment.txt b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml-fragment.txt
new file mode 100644
index 0000000..cb0da5f
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml-fragment.txt
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+b = b
+@document = @document
+@document = @document
+
+C<>&"']]> = C<>&"']]>
+
+<root xmlns:n="http://x"><a><b><n:c>C<>&"']]></n:c></b></a></root>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml-ns_prefix-scope.txt
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml-ns_prefix-scope.txt b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml-ns_prefix-scope.txt
new file mode 100644
index 0000000..bf8e6bd
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml-ns_prefix-scope.txt
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+//e: e in NS namespace-test, e in NS namespace-test
+//n:e: e in NS foo, e in NS foo
+//bar:e: e in NS bar, e in NS bar
+
+Included:
+//n:e: e in NS foo, e in NS foo
+//n:e: e in NS foo, e in NS foo
+
+Imported:
+//n:e: e in NS bar, e in NS bar
+//n:e: e in NS bar, e in NS bar
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml.txt
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml.txt b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml.txt
new file mode 100644
index 0000000..718bba1
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xml.txt
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+ <?firstPi customKey="something"?>
+ firstPi
+ customKey="something"
+ <?secondPi secondPiData?>
+ secondPi
+ secondPiData
+2
+p
+ customKey="something"
+
+<ns1:e11 xmlns:ns1="http://www.foo.com/ns1/">text1</ns1:e11><ns1:e11 xmlns:ns1="http://www.foo.com/ns1/">text2</ns1:e11>
+<ns1:e12 xmlns:ns1="http://www.foo.com/ns1/"><![CDATA[cdata-section1]]></ns1:e12><ns1:e12 xmlns:ns1="http://www.foo.com/ns1/"><![CDATA[cdata-section2<&]]></ns1:e12>
+<ns1:e1 xmlns:ns1="http://www.foo.com/ns1/" a1="v1" a2="v2">
+ <ns1:e11>text1</ns1:e11>
+ <ns1:e12><![CDATA[cdata-section1]]></ns1:e12>
+ </ns1:e1>
+<ns1:e11 xmlns:ns1="http://www.foo.com/ns1/">text1</ns1:e11><ns1:e11 xmlns:ns1="http://www.foo.com/ns1/">text2</ns1:e11>
+a1
+v2
+rootroot
+root
+ root
+ e1
+ e11
+ e12
+ e2
+ e11
+ e12
+ root
+ root
+ e1
+ root
+ e1
+ e11
+ root
+ e1
+ e12
+ root
+ e2
+ root
+ e2
+ e11
+ root
+ e2
+ e12
+cdata-section2<&
+cdata-section2<&
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns1.txt
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns1.txt b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns1.txt
new file mode 100644
index 0000000..69af553
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns1.txt
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
+<book xmlns="http://example.com/eBook">
+ <title>Test Book</title>
+ <chapter>
+ <title>Ch1</title>
+ <para>p1.1</para>
+ <para>p1.2</para>
+ <para>p1.3</para>
+ </chapter>
+ <chapter>
+ <title>Ch2</title>
+ <para>p2.1</para>
+ <para>p2.2</para>
+ </chapter>
+</book>
+
+ <html>
+ <head>
+ <title>Test Book</title>
+ </head>
+ <body>
+ <h1>Test Book</h1>
+
+
+ <h2>Ch1</h2>
+
+
+ <p>p1.1
+
+ <p>p1.2
+
+ <p>p1.3
+
+
+ <h2>Ch2</h2>
+
+
+ <p>p2.1
+
+ <p>p2.2
+
+
+ </body>
+ </html>
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns3.txt
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns3.txt b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns3.txt
new file mode 100644
index 0000000..f028f0a
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns3.txt
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+ <html>
+ <head>
+ <title>Test Book</title>
+ </head>
+ <body>
+ <h1>Test Book</h1>
+
+
+ <h2>Ch1</h2>
+
+
+ <p>p1.1
+
+ <p>p1.2
+
+ <p>p1.3
+
+
+ <h2>Ch2</h2>
+
+
+ <p>p2.1
+
+ <p>p2.2
+
+
+ </body>
+ </html>
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns4.txt
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns4.txt b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns4.txt
new file mode 100644
index 0000000..f028f0a
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns4.txt
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+ <html>
+ <head>
+ <title>Test Book</title>
+ </head>
+ <body>
+ <h1>Test Book</h1>
+
+
+ <h2>Ch1</h2>
+
+
+ <p>p1.1
+
+ <p>p1.2
+
+ <p>p1.3
+
+
+ <h2>Ch2</h2>
+
+
+ <p>p2.1
+
+ <p>p2.2
+
+
+ </body>
+ </html>
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns5.txt
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns5.txt b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns5.txt
new file mode 100644
index 0000000..6e42b09
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/expected/xmlns5.txt
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+No NS = No NS
+x NS = x NS
+y NS = y NS
+x NS = x NS
+No NS = No NS
+- = -
+- = -
+- = -
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/defaultxmlns1.xml
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/defaultxmlns1.xml b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/defaultxmlns1.xml
new file mode 100644
index 0000000..ed289bb
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/defaultxmlns1.xml
@@ -0,0 +1,24 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<root xmlns:x="http://x.com" xmlns:y="http://y.com">
+ <t1>No NS</t1>
+ <x:t2>x NS</x:t2>
+ <y:t3>y NS</y:t3>
+ <t4 xmlns="http://x.com">x NS</t4>
+</root>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xml-ns_prefix-scope.xml
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xml-ns_prefix-scope.xml b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xml-ns_prefix-scope.xml
new file mode 100644
index 0000000..934acac
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xml-ns_prefix-scope.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<root xmlns="http://freemarker.org/test/namespace-test"
+ xmlns:foo="http://freemarker.org/test/foo"
+ xmlns:bar="http://freemarker.org/test/bar">
+ <e>e in NS namespace-test</e>
+ <foo:e>e in NS foo</foo:e>
+ <bar:e>e in NS bar</bar:e>
+</root>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xml.xml
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xml.xml b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xml.xml
new file mode 100644
index 0000000..abf7e96
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xml.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<?firstPi customKey="something"?>
+<?secondPi secondPiData?>
+<ns1:root xmlns:ns1="http://www.foo.com/ns1/">
+ <ns1:e1 a1="v1" a2="v2">
+ <ns1:e11>text1</ns1:e11>
+ <ns1:e12><![CDATA[cdata-section1]]></ns1:e12>
+ </ns1:e1>
+ <ns1:e2>
+ <ns1:e11>text2</ns1:e11>
+ <ns1:e12><![CDATA[cdata-section2<&]]></ns1:e12>
+ </ns1:e2>
+</ns1:root>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlfragment.xml
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlfragment.xml b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlfragment.xml
new file mode 100644
index 0000000..b5578b6
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlfragment.xml
@@ -0,0 +1,19 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<root><a><b><c xmlns="http://x">C<>&"']]></c></b></a></root>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns.xml
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns.xml b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns.xml
new file mode 100644
index 0000000..6f6453e
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns.xml
@@ -0,0 +1,32 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<book xmlns="http://example.com/eBook">
+ <title>Test Book</title>
+ <chapter>
+ <title>Ch1</title>
+ <para>p1.1</para>
+ <para>p1.2</para>
+ <para>p1.3</para>
+ </chapter>
+ <chapter>
+ <title>Ch2</title>
+ <para>p2.1</para>
+ <para>p2.2</para>
+ </chapter>
+</book>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns2.xml
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns2.xml b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns2.xml
new file mode 100644
index 0000000..c8bfc9f
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns2.xml
@@ -0,0 +1,32 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<eb:book xmlns:eb="http://example.com/eBook">
+ <eb:title>Test Book</eb:title>
+ <eb:chapter>
+ <eb:title>Ch1</eb:title>
+ <eb:para>p1.1</eb:para>
+ <eb:para>p1.2</eb:para>
+ <eb:para>p1.3</eb:para>
+ </eb:chapter>
+ <eb:chapter>
+ <eb:title>Ch2</eb:title>
+ <eb:para>p2.1</eb:para>
+ <eb:para>p2.2</eb:para>
+ </eb:chapter>
+</eb:book>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns3.xml
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns3.xml b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns3.xml
new file mode 100644
index 0000000..8502ead
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/models/xmlns3.xml
@@ -0,0 +1,32 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<book xmlns:x="http://x" xmlns:y="http://y">
+ <x:title>Test Book</x:title>
+ <chapter>
+ <y:title>Ch1</y:title>
+ <para>p1.1</para>
+ <para>p1.2</para>
+ <para>p1.3</para>
+ </chapter>
+ <x:chapter>
+ <y:title>Ch2</y:title>
+ <x:para>p2.1</x:para>
+ <y:para>p2.2</y:para>
+ </x:chapter>
+</book>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/default-xmlns.ftl
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/default-xmlns.ftl b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/default-xmlns.ftl
new file mode 100644
index 0000000..4f01835
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/default-xmlns.ftl
@@ -0,0 +1,28 @@
+<#ftl ns_prefixes={"D" : "http://x.com", "y" : "http://y.com"}>
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<#assign r = doc.*[0]>
+${r["N:t1"]?default('-')} = No NS
+${r["t2"]?default('-')} = x NS
+${r["y:t3"]?default('-')} = y NS
+${r["./D:t4"]?default('-')} = x NS
+
+<#assign bool = doc["true()"]>
+${bool?string}
+
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-fragment.ftl
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-fragment.ftl b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-fragment.ftl
new file mode 100644
index 0000000..226215b
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-fragment.ftl
@@ -0,0 +1,26 @@
+<#ftl ns_prefixes = {"n" : "http://x"}>
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+${node?node_name} = b
+${node?root?node_name} = @document
+${node['/']?node_name} = @document
+
+${node['n:c']} = C<>&"']]>
+
+${node?root.@@markup}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-ns_prefix-scope-lib.ftl
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-ns_prefix-scope-lib.ftl b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-ns_prefix-scope-lib.ftl
new file mode 100644
index 0000000..0f0bde2
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-ns_prefix-scope-lib.ftl
@@ -0,0 +1,23 @@
+<#ftl ns_prefixes={ "n": "http://freemarker.org/test/bar", "D": "http://freemarker.org/test/namespace-test" }>
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<#global libResult>//n:e: ${doc['//n:e']}, ${doc.root['n:e']}</#global>
+<#macro m>
+//n:e: ${doc['//n:e']}, ${doc.root['n:e']}
+</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-ns_prefix-scope-main.ftl
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-ns_prefix-scope-main.ftl b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-ns_prefix-scope-main.ftl
new file mode 100644
index 0000000..5b7ce24
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml-ns_prefix-scope-main.ftl
@@ -0,0 +1,36 @@
+<#ftl ns_prefixes={
+ "D": "http://freemarker.org/test/namespace-test",
+ "n": "http://freemarker.org/test/foo",
+ "bar": "http://freemarker.org/test/bar"
+}>
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+//e: ${doc['//D:e']}, ${doc.root.e}
+//n:e: ${doc['//n:e']}, ${doc.root['n:e']}
+//bar:e: ${doc['//bar:e']}, ${doc.root['bar:e']}
+
+Included:
+<#include "xml-ns_prefix-scope-lib.ftl">
+${libResult}
+<@m />
+
+Imported:
+<#import "xml-ns_prefix-scope-lib.ftl" as lib>
+${libResult}
+<@lib.m />
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml.ftl
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml.ftl b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml.ftl
new file mode 100644
index 0000000..b85fc03
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xml.ftl
@@ -0,0 +1,47 @@
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<#-- test processing instructions -->
+<#global PIs = doc._content._ftype("p")>
+<#list PIs as pi>
+ ${pi}
+ ${pi["@target"]._text}
+ ${pi["@data"]._text}
+</#list>
+${PIs?size}
+<#global firstPi = PIs[0]>
+${firstPi._type}
+${firstPi["@customKey"]}
+${doc._registerNamespace("ns", "http://www.foo.com/ns1/")}
+${doc._descendant["ns:e11"]}
+${doc._descendant["ns:e12"]}
+<#global docRoot = doc["ns:root"]>
+${docRoot["ns:e1"]}
+${doc("//ns:e11")}
+${docRoot["ns:e1"]["@a1"]._name}
+${docRoot["ns:e1"]["@a2"]._text}
+${docRoot._children._parent._name}
+${docRoot._children._parent._unique._name}
+<#list doc._descendant as d>
+ ${d._name}
+</#list>
+<#list doc._descendant._ancestorOrSelf as d>
+ ${d._name}
+</#list>
+${docRoot["ns:e2"]["ns:e12"]._text}
+${docRoot["ns:e2"]["ns:e12"]._plaintext}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns1.ftl
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns1.ftl b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns1.ftl
new file mode 100644
index 0000000..8aa893e
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns1.ftl
@@ -0,0 +1,53 @@
+<#ftl ns_prefixes = {"D" : "http://example.com/eBook"}>
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+
+${doc.@@markup}
+
+<#recurse doc >
+
+<#macro book>
+ <html>
+ <head>
+ <title><#recurse .node.title></title>
+ </head>
+ <body>
+ <h1><#recurse .node.title></h1>
+ <#recurse>
+ </body>
+ </html>
+</#macro>
+
+<#macro chapter>
+ <h2><#recurse .node.title></h2>
+ <#recurse>
+</#macro>
+
+<#macro para>
+ <p><#recurse>
+</#macro>
+
+<#macro title>
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro @text>${.node?html}</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns3.ftl
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns3.ftl b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns3.ftl
new file mode 100644
index 0000000..c84ec69
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns3.ftl
@@ -0,0 +1,70 @@
+<#ftl ns_prefixes = {"x" : "http://x", "y" : "http://y"}>
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<#recurse doc >
+
+<#macro book>
+ <html>
+ <head>
+ <title><#recurse .node["x:title"]></title>
+ </head>
+ <body>
+ <h1><#recurse .node["x:title"]></h1>
+ <#recurse>
+ </body>
+ </html>
+</#macro>
+
+<#macro chapter>
+ <h2><#recurse .node["y:title"]></h2>
+ <#recurse>
+</#macro>
+
+<#macro "x:chapter">
+ <h2><#recurse .node["y:title"]></h2>
+ <#recurse>
+</#macro>
+
+<#macro para>
+ <p><#recurse>
+</#macro>
+
+<#macro "x:para">
+ <p><#recurse>
+</#macro>
+
+<#macro "y:para">
+ <p><#recurse>
+</#macro>
+
+<#macro "x:title">
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro "y:title">
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro @text>${.node?html}</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns4.ftl
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns4.ftl b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns4.ftl
new file mode 100644
index 0000000..e97bfc0
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns4.ftl
@@ -0,0 +1,70 @@
+<#ftl ns_prefixes = {"x" : "http://x", "y" : "http://y"}>
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<#recurse doc >
+
+<#macro book>
+ <html>
+ <head>
+ <title><#recurse .node["x:title"]></title>
+ </head>
+ <body>
+ <h1><#recurse .node["x:title"]></h1>
+ <#recurse>
+ </body>
+ </html>
+</#macro>
+
+<#macro chapter>
+ <h2><#recurse .node["y:title"]></h2>
+ <#recurse>
+</#macro>
+
+<#macro 'x:chapter'>
+ <h2><#recurse .node["y:title"]></h2>
+ <#recurse>
+</#macro>
+
+<#macro para>
+ <p><#recurse>
+</#macro>
+
+<#macro 'x:para'>
+ <p><#recurse>
+</#macro>
+
+<#macro 'y:para'>
+ <p><#recurse>
+</#macro>
+
+<#macro "x:title">
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro "y:title">
+ <#--
+ We have handled this element imperatively,
+ so we do nothing here.
+ -->
+</#macro>
+
+<#macro @text>${.node?html}</#macro>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns5.ftl
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns5.ftl b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns5.ftl
new file mode 100644
index 0000000..edc3b4a
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/templates/xmlns5.ftl
@@ -0,0 +1,28 @@
+<#ftl ns_prefixes = {"D": "http://y.com", "xx" : "http://x.com"}>
+<#--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+<#assign r = doc["N:root"]>
+${r["N:t1"][0]?default('-')} = No NS
+${r["xx:t2"][0]?default('-')} = x NS
+${r["t3"][0]?default('-')} = y NS
+${r["xx:t4"][0]?default('-')} = x NS
+${r["//t1"][0]?default('-')} = No NS
+${r["//t2"][0]?default('-')} = -
+${r["//t3"][0]?default('-')} = -
+${r["//t4"][0]?default('-')} = -
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/testcases.xml
----------------------------------------------------------------------
diff --git a/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/testcases.xml b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/testcases.xml
new file mode 100644
index 0000000..ffb42c3
--- /dev/null
+++ b/freemarker-dom/src/test/resources/org/apache/freemarker/dom/templatesuite/testcases.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" ?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+-->
+
+<!DOCTYPE testCases [
+ <!ELEMENT testCases (setting?, testCase*)>
+ <!ELEMENT testCase (setting?)>
+ <!ATTLIST testCase
+ name CDATA #REQUIRED
+ template CDATA #IMPLIED
+ expected CDATA #IMPLIED
+ noOutput CDATA #IMPLIED
+ >
+ <!-- The default of `template` is "${name?keep_before('[#endTN]')}.ftl" -->
+ <!-- The default of `expected` is "${name}.txt" -->
+ <!-- The default of `noOutput` is false -->
+
+ <!ELEMENT setting EMPTY>
+ <!ATTLIST setting
+ auto_import CDATA #IMPLIED
+ source_encoding CDATA #IMPLIED
+ locale CDATA #IMPLIED
+ object_wrapper CDATA #IMPLIED
+ output_encoding CDATA #IMPLIED
+ output_dir CDATA #IMPLIED
+ new_builtin_class_resolver CDATA #IMPLIED
+ url_escaping_charset CDATA #IMPLIED
+ incompatible_improvements CDATA #IMPLIED
+ time_zone CDATA #IMPLIED
+ api_builtin_enabled CDATA #IMPLIED
+ >
+]>
+<!--
+Note that for the incompatible_improvements setting you can specify a list of versions, for example:
+<setting incompatible_improvements="min, 3.0.5, max" />
+-->
+
+<testCases>
+ <setting source_encoding="UTF-8" output_encoding="UTF-8" />
+
+ <testCase name="default-xmlns" />
+ <testCase name="xml-fragment" />
+ <testCase name="xmlns1" />
+ <testCase name="xmlns2" template="xmlns1.ftl" expected="xmlns1.txt" />
+ <testCase name="xmlns3" />
+ <testCase name="xmlns4" />
+ <testCase name="xmlns5" />
+ <testCase name="xml-ns_prefix-scope" template="xml-ns_prefix-scope-main.ftl" />
+</testCases>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/be556897/freemarker-servlet/build.gradle
----------------------------------------------------------------------
diff --git a/freemarker-servlet/build.gradle b/freemarker-servlet/build.gradle
index 41a8302..c0710b9 100644
--- a/freemarker-servlet/build.gradle
+++ b/freemarker-servlet/build.gradle
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+
title = "Apache FreeMarker Servlet and JSP support"
description = """\
FreeMarker template engine, Servlet and JSP support. \