[
https://issues.apache.org/jira/browse/FREEMARKER-41?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15734718#comment-15734718
]
Per Olsson commented on FREEMARKER-41:
--------------------------------------
It should be implemented for example as the normalize() function in
ElementImpl.java from the Xerces project
https://svn.apache.org/repos/asf/xerces/java/trunk/src/org/apache/xerces/dom/ElementImpl.java
> 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)