You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by "Daniel Dekany (JIRA)" <ji...@apache.org> on 2016/12/09 00:32:59 UTC
[jira] [Comment Edited] (FREEMARKER-41) XPathSupport executeQuery
doesn't handle text() in models that isn't normalized
[ https://issues.apache.org/jira/browse/FREEMARKER-41?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15733835#comment-15733835 ]
Daniel Dekany edited comment on FREEMARKER-41 at 12/9/16 12:32 AM:
-------------------------------------------------------------------
I'm not sure how to solve this. The Xalan XPath query result set simply only contains the first text node, instead of two nodes. I could work that around when I convert a text node to text, as I could check if the {{nextSibling}} DOM node is text too, and then append it to the result. But I'm not sure if I break something with that. Like if {{text()\[1]}} returns "SA" and {{text()\[2]}} returns "PLE" on some implementations (Xalan 2.7.0 returns empty set for the last), even maybe on a future version of Xalan, then {{$\{text()\[1]}}} should really only print "SA".
was (Author: ddekany):
I'm not sure how to solve this. The Xalan XPath query result set simply only contains the first text node, instead of two nodes. I could work that around when I convert a text node to text, as I could check if the {{nextSibling}} DOM node is text too, and then append it to the result. But I'm not sure if I break something with that. Like if {{text()\[1]}} returns "SA" and {{text()\[2]}} returns "PLE" on some implementations (Xalan 2.7.0 returns empty set for the last), even maybe on a future version of Xalan, then {{${text()\[1]}}} should really only print "SA".
> 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)