将 Freemarker DocumentModel 与命名空间一起使用
Using Freemarker DocumentModel with namespaces
我收到了一份 XML 文档,其中包含我需要处理的命名空间信息。根据我在文档中阅读的所有内容,我应该能够将 XML 文档传递给模板并在模板中使用 XPath 来访问文档元素。
我能够在不包含名称空间的文档上成功执行此操作。但是,一旦我引入名称空间,我就会遇到异常。这是一些示例 XML:
<?xml version="1.0" encoding="UTF-8" ?>
<ns:a xmlns:ns="http://whosebug.com/">
<ns:b>
<ns:c>Element c</ns:c>
<ns:d>
<ns:e>Element e</ns:e>
</ns:d>
</ns:b>
</ns:a>
这是我的模板:
<#ftl ns_prefixes={
"ns":"http://whosebug.com/"}
>
${doc.@@markup}
${doc["/ns:a/ns:b/ns:c"]}
${doc["/ns:a/ns:b/ns:d/ns:e"]}
当我将此模板应用于 XML 时,出现以下错误:
Nov 08, 2015 6:31:41 PM freemarker.log._JULLoggerFactory$JULLogger error
SEVERE: Error executing FreeMarker template
FreeMarker template error:
For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), but this has evaluated to a sequence+hash (wrapper: f.e.dom.NodeListModel):
==> doc["/ns:a/ns:b/ns:c"] [in template "freemarker.ftl" at line 6, column 3]
----
Tip: This XML query result can't be used as string because for that it had to contain exactly 1 XML node, but it contains 0 nodes. That is, the constructing XML query has found no matches.
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: ${doc["/ns:a/ns:b/ns:c"]} [in template "freemarker.ftl" at line 6, column 1]
----
我最初没有考虑这个,但这是我应用模板的代码。
public static void main(String[] args) {
try {
File f = new File("c:/temp/freemarker.xml");
Configuration c = new Configuration();
c.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
c.setDefaultEncoding("UTF-8");
c.setDirectoryForTemplateLoading(new File("c:/temp"));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(f);
Element note = doc.getDocumentElement();
NodeModel.simplify(note);
NodeModel.useJaxenXPathSupport();
Map<String, Object> root = new HashMap<String, Object>();
root.put("doc", note);
Template template = c.getTemplate("freemarker.ftl");
Writer out = new StringWriter();
template.process(root, out);
System.out.println(out);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
正如我所说,没有名称空间也能正常工作。不幸的是,我无法删除名称空间信息,因为可能会发生名称冲突,需要名称空间来确定引用的是哪个元素。
谁能告诉我我做错了什么?或者这可能是一个错误?
谢谢!
您的示例 XML 中缺少 xmlns:ns="http://whosebug.com/"
。如果我添加它,那么它对我有用。
我收到了一份 XML 文档,其中包含我需要处理的命名空间信息。根据我在文档中阅读的所有内容,我应该能够将 XML 文档传递给模板并在模板中使用 XPath 来访问文档元素。
我能够在不包含名称空间的文档上成功执行此操作。但是,一旦我引入名称空间,我就会遇到异常。这是一些示例 XML:
<?xml version="1.0" encoding="UTF-8" ?>
<ns:a xmlns:ns="http://whosebug.com/">
<ns:b>
<ns:c>Element c</ns:c>
<ns:d>
<ns:e>Element e</ns:e>
</ns:d>
</ns:b>
</ns:a>
这是我的模板:
<#ftl ns_prefixes={
"ns":"http://whosebug.com/"}
>
${doc.@@markup}
${doc["/ns:a/ns:b/ns:c"]}
${doc["/ns:a/ns:b/ns:d/ns:e"]}
当我将此模板应用于 XML 时,出现以下错误:
Nov 08, 2015 6:31:41 PM freemarker.log._JULLoggerFactory$JULLogger error
SEVERE: Error executing FreeMarker template
FreeMarker template error:
For "${...}" content: Expected a string or something automatically convertible to string (number, date or boolean), but this has evaluated to a sequence+hash (wrapper: f.e.dom.NodeListModel):
==> doc["/ns:a/ns:b/ns:c"] [in template "freemarker.ftl" at line 6, column 3]
----
Tip: This XML query result can't be used as string because for that it had to contain exactly 1 XML node, but it contains 0 nodes. That is, the constructing XML query has found no matches.
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: ${doc["/ns:a/ns:b/ns:c"]} [in template "freemarker.ftl" at line 6, column 1]
----
我最初没有考虑这个,但这是我应用模板的代码。
public static void main(String[] args) {
try {
File f = new File("c:/temp/freemarker.xml");
Configuration c = new Configuration();
c.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
c.setDefaultEncoding("UTF-8");
c.setDirectoryForTemplateLoading(new File("c:/temp"));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(f);
Element note = doc.getDocumentElement();
NodeModel.simplify(note);
NodeModel.useJaxenXPathSupport();
Map<String, Object> root = new HashMap<String, Object>();
root.put("doc", note);
Template template = c.getTemplate("freemarker.ftl");
Writer out = new StringWriter();
template.process(root, out);
System.out.println(out);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
正如我所说,没有名称空间也能正常工作。不幸的是,我无法删除名称空间信息,因为可能会发生名称冲突,需要名称空间来确定引用的是哪个元素。
谁能告诉我我做错了什么?或者这可能是一个错误?
谢谢!
您的示例 XML 中缺少 xmlns:ns="http://whosebug.com/"
。如果我添加它,那么它对我有用。