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)