You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by "Per Olsson (JIRA)" <ji...@apache.org> on 2016/11/30 10:43:00 UTC
[jira] [Created] (FREEMARKER-41) XPathSupport executeQuery doesn't
handle text() in models that isn't normalized
Per Olsson created FREEMARKER-41:
------------------------------------
Summary: XPathSupport executeQuery doesn't handle text() in models that isn't normalized
Key: FREEMARKER-41
URL: https://issues.apache.org/jira/browse/FREEMARKER-41
Project: Apache Freemarker
Issue Type: Bug
Components: engine
Affects Versions: 2.3.25-incubating
Reporter: Per Olsson
XPath expressions that contains text() doesn't evaluate to the correct value when the model isn't normalized and includes multiple text nodes. This will happen when the xml-parser creates multiple text nodes due to performance or memory reasons and is a fully normal behaviour.
The solution in the function executeQuery with the NodeIterator (files: freemarker/ext/dom/SunInternalXalanXPathSupport.java and freemarker/ext/dom/XalanXPathSupport.java) doesn't handle adjacent(siblings) textnodes. The problem probably also exists for CDATA nodes. I don't know if the jaxen solution behaves in the same manner.
{code:title=...XPathSupport.java|borderStyle=solid}
synchronized public TemplateModel executeQuery(Object context, String xpathQuery) throws TemplateModelException {
...
NodeIterator nodeIterator = xresult.nodeset();
Node n;
do {
n = nodeIterator.nextNode();
if (n != null) {
result.add(n);
}
} while (n != null);
...
{code}
Sample code to reproduce
{code:title=Reproduce.java|borderStyle=solid}
Configuration cfg = new Configuration(Configuration.VERSION_2_3_25);
cfg.setDefaultEncoding("UTF-8");
ClassTemplateLoader ctl = new ClassTemplateLoader(App.class, "/");
cfg.setTemplateLoader(ctl);
// --- sample.ftl ---
// <#ftl>
// Text:${model["//root/text()"]}
// Node:${model["//root"]}
Template temp = cfg.getTemplate("sample.ftl");
// --- Model ---
// Element:root
// |- TextNode:SA
// |- TextNode:MPLE
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element rootElement = doc.createElement("root");
doc.appendChild(rootElement);
Text text = doc.createTextNode("SA");
rootElement.appendChild(text);
text = doc.createTextNode("MPLE");
rootElement.appendChild(text);
Map<String, Object> model = new HashMap<String, Object>();
model.put("model", doc);
StringWriter sw = new StringWriter();
temp.process(model, sw);
System.out.println(sw.toString());
// --- Actual output ---
// Text:SA
// Node:SAMPLE
// --- Expected output ---
// Text:SAMPLE
// Node:SAMPLE
{code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)