[
https://issues.apache.org/jira/browse/FREEMARKER-41?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15737589#comment-15737589
]
Daniel Dekany commented on FREEMARKER-41:
-----------------------------------------
But that basically does the same as {{NodeModel.simplify(Node)}}, which users
are recommended to apply on the DOM tree before passing it to FreeMarker. My
understanding was that you don't want to do such normalization. Regardless,
it's true that the result of {{text()}} with Xalan is flawed if you have an
non-normalized (non-simplified) tree, but {{ElementIml.normalize()}} doesn't
help there, similarly as {{NodeModel.simplify(Node)}} doesn't, because the
premise is that the tree is non-normalized. When and where to call it, if I'm
not supposed to change the DOM tree?
BTW, simply not using {{text()}} and just print the parent element is another
solution, as you have shown. Even if the result with Xalan was correct, just as
with Jaxen, you couldn't print directly, as it's two text nodes, not one, and
currently you can only print a node set that contains exactly one node (though,
if they are all text nodes, this could be changed).
> 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)