freemarker-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Daniel Dekany (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (FREEMARKER-41) XPathSupport executeQuery doesn't handle text() in models that isn't normalized
Date Sat, 10 Dec 2016 09:45:58 GMT

    [ 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)

Mime
View raw message