freeMarker(十三)——XML处理指南之揭示XML文档
学习笔记,选自freeMarker中文文档,译自 Email: ddekany at users.sourceforge.net
前言
尽管 FreeMarker 最初被设计用作Web页面的模板引擎, 对于2.3版本来说,它的另外一个应用领域目标是: 转换XML到任意的文本输出(比如HTML)。 因此,在很多情况下,FreeMarker 也是一个可选的XSLT。
从技术上来说,在转换XML文档上没有什么特别之处。 它和你使用 FreeMarker 做其他事情都是一样的: 你将XML文档丢到数据模型中(和其他可能的变量), 然后你将FTL模板和数据模型合并来生成输出文本。 对于更好的XML处理的额外特性是结点FTL变量类型 (在通用的树形结构中象征一个结点,不仅仅是对XML有用)和用内建函数, 指令处理它们,你使用的XML包装器会暴露XML文档,并将作为模板的FTL变量。
使用 FreeMarker 和XSLT有什么不同?FTL语言有常规的命令式/过程式的逻辑。 另一方面,XSLT是声明式的语言,由"很聪明"的人设计出来, 所以它并不能轻易吸收它的逻辑,也不会在很多情况下使用。而且它的语法也非常繁琐。 然而,当你处理XML文档时,XSLT的"应用模板"方法可以非常方便, 因此 FreeMarker 支持称作"访问者模式"的相似事情。 所以在很多应用程序中,写FTL的样式表要比写XSLT的样式表容易很多。 另外一个根本的不同是FTL转换结点树到文本,而XSLT转换一课树到另一棵树。 所以你不能经常在使用XSLT的地方使用 FreeMarker。
1.结点树
我们使用如下示例的XML文档:
<book>
<title>Test Book</title>
<chapter>
<title>Ch1</title>
<para>p1.1</para>
<para>p1.2</para>
<para>p1.3</para>
</chapter>
<chapter>
<title>Ch2</title>
<para>p2.1</para>
<para>p2.2</para>
</chapter>
</book>
W3C 的 DOM 定义XML文档模型为结点树。上面XML的结点树可以被视为:
document
|
+- element book
|
+- text "\n "
|
+- element title
| |
| +- text "Test Book"
|
+- text "\n "
|
+- element chapter
| |
| +- text "\n "
| |
| +- element title
| | |
| | +- text "Ch1"
| |
| +- text "\n "
| |
| +- element para
| | |
| | +- text "p1.1"
| |
| +- text "\n "
| |
| +- element para
| | |
| | +- text "p1.2"
| |
| +- text "\n "
| |
| +- element para
| |
| +- text "p1.3"
|
+- element
|
+- text "\n "
|
+- element title
| |
| +- text "Ch2"
|
+- text "\n "
|
+- element para
| |
| +- text "p2.1"
|
+- text "\n "
|
+- element para
|
+- text "p2.2"
请注意,烦扰的 "\n " 是行的中断 (这里用 \n 指示,在FTL字符串中使用转义序列) 和标记直接的缩进空格。
请注意和DOM相关的术语:
一棵树最上面的结点称为根 root,在XML文档中,它通常是"文档"结点, 而不是最顶层元素(本例中的
book)。如果B是A的 直接 后继, 我们说B结点是A结点的子结点 child。比如, 两个
chapter元素是book元素的子结点, 但是para元素就不是。如果A是B的 直接 前驱,也就是说, 如果B是A的子结点,我们说结点A是结点B的父结点 parent。比如,
book元素是两个chapter元素的父结点, 但是它不是para元素的父结点。XML文档中可以出现几种成分,比如元素,文本,注释,处理指令等。 所有这些成分都是DOM树的结点,所以就有元素结点,文本结点,注释结点等。 原则上,元素的属性也是树的结点--它们是元素的子结点--, 但是,通常我们(还有其他XML相关的技术)不包含元素的子结点。 所以基本上它们不被记为子结点。
程序员将DOM树的文档结点放到 FreeMarker 的数据模型中, 那么模板开发人员可以以变量为出发点来使用DOM树。
FTL中的DOM结点和 node variables 结点变量对应。这是变量类型,和字符串,数字,哈希表等类型相似。 结点变量类型使得 FreeMarker 来获取一个结点的父结点和子结点成为可能。 这是技术上需要允许模板开发人员在结点间操作,也就是,使用node 内建函数 或者 visit 和 recurse 指令;我们会在后续章节中展示它们的使用。
2.将XML放在数据模型中
创建一个简单的程序来运行下面的示例是非常容易的。
/* Create a data-model */
Map root = new HashMap();
root.put(
"doc",
freemarker.ext.dom.NodeModel.parse(new File("the/path/of/the.xml")));
然后你可以在基本的输出(通常是终端屏幕) 中得到一个程序可以输出XML转换的结果。
注意:
parse方法默认移除注释和处理指令结点。 参见API文档获取详细信息。NodeModel也允许你直接包装org.w3c.dom.Node。 首先你也许想用静态的实用方法清空DOM树,比如NodeModel.simplify或你自定义的清空规则。
请注意,有可用的工具,你可以使用它们从XML文档中来生成文件, 所以你不需对通用任务来写自己的代码。
参考程序开发指南补充知识之 和Ant一起使用FreeMarker
译自 Email: ddekany at users.sourceforge.net
freeMarker(十三)——XML处理指南之揭示XML文档的更多相关文章
- 突发奇想之:源码及文档,文档包括源码---xml格式的源码,文档源码合并;注释文档化,文档代码化;
目前源码和文档一般都是分开的,我在想为什么 源码不就是最好的文档么? 但是一般源码都是文本text的,格式化需要人为统一规范,所以源码中的文档在现实中不是那么的易于实践. 而且 源码 不能包括图片.附 ...
- xml基础之二(XML结构【2】)DTD文档模版
xml基础之二(XML结构[2])DTD文档模版 xml 模板 文档结构 我们知道XML主要用于数据的存储和传输,所以无论是自定义还是外部引用DTD模板文档,都是为了突出数据的存储规范.DTD(文档 ...
- 这可能是最详细的 iOS 学习入门指南(含书目/文档/学习资料)
1 零基础小白如何进行 iOS 系统学习 首先,学习目标要明确: 其次,有了目标,要培养兴趣,经常给自己一些正面的反馈,比如对自己的进步进行鼓励,在前期小步快走: 再次,学技术最重要的一点就是多动手. ...
- java通过freemarker导出包含富文本图片的word文档
废话不多说,进入正题! 本文重点在于:对富文本图片的导出(基础的freemarker+word模板导出这里不做详细解说哈) 参考文章:http://www.cnblogs.com/liaofeifig ...
- ElasticSearch权威指南学习(分布式文档存储)
路由文档到分片 当你索引一个文档,它被存储在单独一个主分片上.Elasticsearch是如何知道文档属于哪个分片的呢?当你创建一个新文档,它是如何知道是应该存储在分片1还是分片2上的呢? 进程不能是 ...
- Java获取XML节点总结之读取XML文档节点
dom4j是Java的XML API,用来读写XML文件的.目前有很多场景中使用dom4j来读写xml的.要使用dom4j开发,需要下载导入dom4j相应的jar文件.官网下载:http://www. ...
- 四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)
众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...
- xml语法、DTD约束xml、Schema约束xml、DOM解析xml
今日大纲 1.什么是xml.xml的作用 2.xml的语法 3.DTD约束xml 4.Schema约束xml 5.DOM解析xml 1.什么是xml.xml的作用 1.1.xml介绍 在前面学习的ht ...
- 浅谈用java解析xml文档(四)
继续接上一文,这一阵子因为公司项目加紧,导致最后一个解析xml文档的方式,还没有总结,下面总结使用dom4J解析xml. DOM4J(Document Object Model for Java) 使 ...
随机推荐
- 从动态获取div高度的问题展开来看
ps 可能篇幅比较长,请大家耐心看看 今天有人在群里问我 动态获取高度怎么获取 我就说jq中的outerHeight. height .innerHeight 原生的height clientH ...
- 全文检索引擎Solr的配置
描述: 在Linux环境下实现高速的全文检索 一.当前环境: CentOS (Linux) 6.3 64 bit 二.所需软件 1.Java的JDK Java jdk 1.7.0[注意:solr5.x ...
- Linq实现between拓展
先写一个拓展方法 static class Ext { public static IQueryable<TSource> Between<TSource, TKey> (th ...
- Qt插件开发入门(两种方法:High-Level API接口,Low-Level API接口)
Qt中为我们提供了两种开发插件的方式.一种是使用High-Level API接口,一种是使用Low-Level API接口.所谓High-Level API 是指通过继承Qt为我们提供的特定的插件基类 ...
- Swift学习笔记十一:方法
方法是与某些特定类型相关联的功能/函数.在Swift中,结构体和枚举能够定义方法:其实这是Swift与C/Objective-C的主要差别之中的一个. 在Objective-C中,类是唯一能 ...
- scala与java之间的那些事
scala与java之间的关系,我认为可以用一句话来开头:scala来源于java,但又高于java. scala的设计者Martin Odersky就是一个JAVA控,这位牛人设计了javac和编写 ...
- iOS 读取本地Json文件
之前写过类似的方法 今天写这个 的目的是 应对开发过程中面对 服务端数据刚定下模型 但是接口不通 的情况下 不耽误客户端开发进度 + (id)getJsonDataJsonname:(NSString ...
- 解决编译caffe2遇到的坑
首先我们要从源码克隆caffe2的库: git clone --recursive https://github.com/caffe2/caffe2.git 执行下载过程会报这样的错: Cloning ...
- leetcode 1049 Last Stone Weight II(最后一块石头的重量 II)
有一堆石头,每块石头的重量都是正整数. 每一回合,从中选出任意两块石头,然后将它们一起粉碎.假设石头的重量分别为 x 和 y,且 x <= y.那么粉碎的可能结果如下: 如果 x == y,那么 ...
- Javascript中闭包的个人理解
Javascript的一个特殊点就在于它的闭包和回调特性,这两个特性让初学Javascript的我是云里雾里,至今仍在苦苦摸索与理解.在一番苦思之后,整理了一下资料,将自己的理解思路记录下来,以 ...