ToDoList样式表:教程
介绍 我刚刚为TDL构建了一个定制样式表,这是我的第一个XSLT文件,对于从未接触过XSLT文件的人来说,这不是一项容易的任务。使用TDL交付的样式表不适合初学者学习,这并不奇怪,但令我惊讶的是,所有所需的信息都分布在如此多的地方。 所以,我写这篇文章是为了把我发现有用的东西放在一起,希望它能帮助您为ToDoList创建自己的样式表。 记住,英语对我来说还是一门外语。请随意报告错误。 背景 对于初学者来说,了解XML格式的基本知识更佳,了解HTML也会有帮助。对于高级样式表,必须了解XML、HTML和XPath。 XML文件格式 快速介绍XML文件格式。ToDoList的任务列表和样式表是XML文件。 XML文件的基本结构是元素,元素由开始标记和结束标记组成。 隐藏,复制Code
<TODOLIST> </TODOLIST>
元素的开始标记可以包含属性,值与每个attibute相关联,值始终是字符串,甚至是数值。 隐藏,复制Code
<TODOLISTPROJECTNAME="My TaskList"FILEFORMAT="10"> </TODOLIST>
元素可以包含嵌套在两个标记之间的一些文本或其他元素。 隐藏,复制Code
<TODOLISTPROJECTNAME="My TaskList"FILEFORMAT="10"> <TASKTITLE="My first Task"> <TASKTITTLE="My sub task"> <COMMENTS>My comments</COMMENTS> </TASK> </TASK> <TASKTITLE="My second Task"> </TASK> </TODOLIST>
XML文件由一个主元素组成,其中包含嵌套的所有内容。就XML文件本身而言,它被组织成树,单个主元素是树的根。 在以前snipset: TODOLIST是根元素。它还包含其他元素。任务是一个元素。它还包含其他元素。注释是一个元素。它包含文本。PROJECTNAME是todolist文件格式的属性是todolist title任务的属性 任务列表包含更多的元素和属性。 关于XML、XSLT、HTML或XPath的更多细节,我推荐w3schools.com 首先,获取一个TDL样式表示例 首先,我搜索了一个示例样式表,并发现文章XSL Transform for ToDoList包含了一个TDL样式表,目的是作为一个示例。我的第一个实验相当令人沮丧,直到我明白这个示例有很多bug。 下面是对样式表的更正。 任何需要它的地方,都要替换它 隐藏,复制Code
<xsl:apply-templates/>
与 隐藏,复制Code
<xsl:apply-templatesselect="TASK"/>
,替换 隐藏,复制Code
... "@COMMENTS"
与 隐藏,复制Code
... "COMMENTS"
经过修正后,示例工作得好得多。更正后的文件是bpsToDoListStyler_Rev019.xsl。 试验示例样式表 为了处理这个示例,我建议从树视图开始并获得所有属性。输出格式为HTML,可用于打印、预览或转换任务列表。很多选项都被注释掉了,只要取消注释就可以看到会追加什么。 ToDoList如何处理样式表 TDL可以将样式表用于打印、导出或转换等操作。在每种情况下,TDL都会生成一个反映实际设置的特定临时任务列表,样式表将应用于该临时任务列表。 特定的任务列表是使用这些准则来构建的: 如果在树视图中,临时列表将是树,如果在列表视图中,临时列表将是平面的。将使用实际排序。对话框允许您选择包含哪些任务和哪些属性。 选择你想要的结果: 打印:输出将被打印在纸上。预览:输出结果在屏幕上显示与打印结果相同。转换:如果使用文本或HTML格式,输出将保存在磁盘上,并显示在internet导航器上。打印和预览的区别在于HTML不局限于可打印特性。转换的另一种用法是生成其他XML文件。 临时任务列表文件存储在目录%temp%中,文件名为任务列表名称后接. intermediator .txt。MyTasks的临时文件。tdl将是%temp%目录中的mytask . intermediator .txt。在文本编辑器中打开以查看结构以及文件中的元素和属性。 TDL样式表的缺陷 空的结果 存在的问题: 这一切都在标题中。结果为空。 答案是: 第一种可能是编译错误。你必须找出错误所在并加以改正。不幸的是,TDL没有提供任何关于出错原因的基本线索。如果您没有任何类型的调试器,最好是从一个通用的工作示例开始,然后通过测试进行增量更改,以验证每个更改。 第二种可能是没有匹配或没有输出。首先,确保您的样式表总是在根匹配时输出一些内容。要做到这一点,最简单的方法是确保将任务列表的内容放到结果中。通过获得结果,可以确保样式表编译成功。如果你没有得到你应该得到的,一定是逻辑上的错误的样式表。 使用<xsl:template match="/">模板 存在的问题: 显然,没有遍历XML树,如果 隐藏,复制Code
<xsl:templatematch="/">
被替换为 隐藏,复制Code
<xsl:templatematch="/TODOLIST">
,一切正常。 答案是: 整个技巧就是<xsl:template match="/">当需要任务时,匹配XML文档和子元素是TODOLIST。 如果您有一个文档匹配模板,那么还需要一个根匹配模板,因为前者必须调用后者。 口音在样式表 存在的问题: 当您使用重音符号时,文件编码可能会成为一个问题,这个问题非常大,即使只是在注释中,也足以导致编译失败。您需要应用正确的编码。 答案是: 为了解决这个问题,有两个地方需要检查: 在xml标签中声明编码: 隐藏,复制Code< ?编码="utf-8" ?> 在您的文本编辑器中,选择符合您需要的字符编码:UTF-8, UTF-16, iso-8859-1… UTF-8通常是一个不错的选择。在任何情况下,确保两者都匹配。 在没有“模板”的元素上执行“应用模板” 存在的问题: 这就是TDL示例中的错误。通用 隐藏,复制Code
<xsl:apply-templates/>
将匹配当前元素中的任何元素。当您遇到注释(或任何不是任务的元素)时,就会出现问题。由于注释没有匹配的模板,因此应用默认行为,注释中的文本被简单地转储到输出。 这就是在运行原始的错误示例(如文件bpsToDoListStyler_Rev018.xsl)时出现未格式化文本的原因。 答案是: 仅对嵌套任务使用应用程序模板。 隐藏,复制Code
<xsl:apply-templatesselect="TASK"/>
Nota:同样的问题也适用于TDL 6.9.6和更早的样式表:Project-Overview-HTML。xsl, SimpStyler0.2。xsl, TodoListStyler_Firefox。xsl和TodoListStyler_v1.5.xsl 另一种选择是声明一个模板来匹配所有内容。 隐藏,复制Code
<xsl:templatematch="*">
小心你所做的事情,如果没有掌握它,它就像危险一样强大,它很容易导致不想要的结果。 XML样式表snipsets XML文件的组织方式类似于树,而XSLT基本上是在应用转换时遍历树,如果输入树结构与输出树结构不匹配,可以通过更复杂的编程来完成更复杂的转换。 有些例子使用html标记,请参阅下一章,了解样式表中的html标记。 XSLT的评论 建议:在不明显的地方用注释记录xslt样式表。 隐藏,复制Code
<!-- My Comments anywhere I need -->
初学者经常认为记录是浪费时间,这是错误的。您会发现,在6个月或一年后重新查看代码并不是浪费时间,因为注释可以帮助您回忆代码的意图。 样式表组织 xslt基于模板匹配语言。这意味着没有显式的入口点,也没有显式的匹配模板链接,它是数据驱动的。如果有多个模板与当前数据匹配,这不是错误,只是在运行时通过遵循一些规则选择正确的模板。 样式表发射 样式表总是先尝试执行与整个文档匹配的模板。 隐藏,复制Code
<xsl:templatematch="/">
如果失败,解释器将寻找匹配XML文件根的模板。就像 隐藏,复制Code
<xsl:templatematch="/TODOLIST">
它是一个只匹配名为TODOLIST的根元素的模板。或 隐藏,复制Code
<xsl:templatematch="TODOLIST">
该模板只匹配名为TODOLIST的元素,不需要匹配根元素。 匹配的模板 注意,XSLT代码中没有链接匹配的模板。 隐藏,复制Code
<xsl:apply-templates/>
将动态决定调用哪个匹配模板以及调用顺序。为了对样式表的执行保持一定的控制,最好使用语法 隐藏,复制Code
<xsl:apply-templatesselect="TASK"/>
指定要匹配的元素。 你好,世界 经典的一个。HelloWord看到文件。xsl表示完整示例。 隐藏,复制Code
<?xmlversion="1.0"?> <xsl:stylesheetxmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0"> <xsl:outputmethod="text"/> <xsl:templatematch="/"> <xsl:text>Hello Word</xsl:text> </xsl:template> </xsl:stylesheet>
& lt; xsl:输出方法= " text " /比;告诉输出是原始文本,没有格式化,什么都没有,只是文本。 & lt; xsl:模板匹配= " / "比;匹配任何文档的根元素。 元素& lt; xsl: text>包围您想要输出的文本 你好,基于网络 参见文件TDLSS 1。xsl表示完整示例。 隐藏,复制Code
<?xmlversion="1.0"?> <xsl:stylesheetxmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0"> <xsl:outputmethod="html"indent="yes"doctype-public="-//W3C//DTD HTML 4.01 Transitional//EN"/> <xsl:templatematch="/TODOLIST"> <xsl:elementname="html"> <xsl:elementname="body"> <xsl:text>Hello ToDoList</xsl:text> </xsl:element> </xsl:element> </xsl:template> </xsl:stylesheet>
输出方法="html"…告知输出是html页面,具有所有常见的格式,但代价有点复杂。 & lt; xsl:模板匹配= " /基于网络”在将只匹配名为TODOLIST的根元素,这是任务列表的根元素的名称。 读属性值 参见文件TDLSS 2。xsl表示完整示例。 隐藏,复制Code
<xsl:template match="TODOLIST"> <xsl:element name="html"> <xsl:element name="head"> <xsl:element name="title"> <xsl:value-of select="@PROJECTNAME" /> </xsl:element> </xsl:element> <xsl:element name="body"> <xsl:value-of select="@PROJECTNAME" /> <xsl:element name="br" /> <xsl:value-of select="@FILENAME" /> <xsl:element name="br" /> </xsl:element> </xsl:element> </xsl:template>
& lt; xsl:是选择= " @PROJECTNAME " /比;输出PROJECTNAME属性的值。 遍历树 参见文件TDLSS 3。xsl表示完整示例。 隐藏,复制Code
<xsl:template match="TODOLIST"> <xsl:element name="html"> <xsl:element name="head"> <xsl:element name="title"> <xsl:value-of select="@PROJECTNAME" /> </xsl:element> </xsl:element> <xsl:element name="body"> <xsl:value-of select="@PROJECTNAME" /> <xsl:element name="br" /> <xsl:value-of select="@FILENAME" /> <xsl:element name="br" /> <xsl:element name="br" /> <xsl:apply-templates select="TASK" /> </xsl:element> </xsl:element> </xsl:template> <xsl:template match="TASK"> <xsl:value-of select="@TITLE" /> <xsl:element name="br" /> </xsl:template>
select="TASK" />寻找名为TASK的元素,它是TODOLIST元素的子元素,并将应用template <每次出现。 递归地遍历树 参见文件TDLSS 4。xsl表示完整示例。 隐藏,复制Code
<xsl:template match="TASK"> <xsl:value-of select="@TITLE" /> <xsl:element name="br" /> <xsl:apply-templates select="TASK" /> </xsl:template>
select="TASK" />是使树遍历递归的原因。 读取文本元素值 参见文件TDLSS 5。xsl表示完整示例。 隐藏,复制Code
<xsl:templatematch="TASK"> <xsl:value-ofselect="@TITLE"/> <xsl:elementname="br"/> <xsl:text>CATEGORY: </xsl:text> <xsl:value-ofselect="CATEGORY"/> <xsl:elementname="br"/> <xsl:text>COMMENTS: </xsl:text> <xsl:value-ofselect="COMMENTS"/> <xsl:elementname="br"/> <xsl:elementname="br"/> <xsl:apply-templatesselect="TASK"/> </xsl:template>
select="COMMENTS" />输出COMMENTS文本元素的值。 单一的条件:如果 参见文件TDLSS 6。xsl表示完整示例。 隐藏,复制Code
<xsl:iftest="COMMENTS"> <xsl:text>COMMENTS: </xsl:text> <xsl:value-ofselect="COMMENTS"/> <xsl:elementname="br"/> </xsl:if>
xsl: if 当测试为真时做某事,当测试为假时不做任何事。 多个条件:选择 参见文件TDLSS 7。xsl表示完整示例。 隐藏,复制Code
<xsl:choose> <xsl:whentest="COMMENTS"> <xsl:text>COMMENTS: </xsl:text> <xsl:value-ofselect="COMMENTS"/> <xsl:elementname="br"/> </xsl:when> <xsl:otherwise> <xsl:text>No COMMENT</xsl:text> </xsl:otherwise> </xsl:choose>
choose是一种多条件结构。第一个是执行结构时(为真),如果没有测试为真,则执行其他结构。 调用一个模板 参见文件TDLSS 8。xsl表示完整示例。 隐藏,复制Code
<xsl:call-templatename="fix-breaks"> <xsl:with-paramname="text"> <xsl:value-ofselect="COMMENTS"/> </xsl:with-param> </xsl:call-template> . . . <xsl:templatename="fix-breaks"> <xsl:paramname="text"/> . . . </xsl:template>
模板名="fix-break ">都是其他语言的子程序。它们由<xsl:call-template name="fix-break "调用> 固定休息 参见文件TDLSS 8。xsl表示完整示例。 隐藏,复制Code
<xsl:templatename="fix-breaks"> <xsl:paramname="text"/> <xsl:choose> <xsl:whentest="contains($text,' ')"> <xsl:value-ofselect="substring-before($text,' ')"/> <xsl:elementname="br"/> <xsl:call-templatename="fix-breaks"> <xsl:with-paramname="text"> <xsl:value-ofselect="substring-after($text,' ')"/> </xsl:with-param> </xsl:call-template> </xsl:when> <xsl:otherwise> <xsl:value-ofselect="$text"/> </xsl:otherwise> </xsl:choose> </xsl:template>
多行文本需要为html输出进行修复,因为CRLF不能理解,必须用<br/>替换。 获取任务路径 参见文件TDLSS 9。xsl表示完整示例。 隐藏,复制Code
<xsl:templatename="get_Task_Ancestors"> <xsl:iftest="count(ancestor::TASK)>0"> <xsl:for-eachselect="(ancestor::TASK)"> <xsl:value-ofselect="@TITLE"/> <xsl:text> - </xsl:text> </xsl:for-each> </xsl:if> </xsl:template>
此模板仅在任务嵌套(树形视图)时有效。它列出了从根开始的父节点的标题。 显示任务嵌套 TDLSS10看到文件。xsl表示完整示例。 在html中,通过简单的嵌套列表,列表是显示缩进的自然方式。 隐藏,复制Code
<xsl:templatematch="/TODOLIST"> <xsl:elementname="html"> <xsl:elementname="head"> <xsl:elementname="title"> <xsl:value-ofselect="@PROJECTNAME"/> </xsl:element> </xsl:element> <xsl:elementname="body"> . . . <xsl:elementname="ul"> <xsl:apply-templatesselect="TASK"/> </xsl:element> </xsl:element> </xsl:element> </xsl:template> <xsl:templatematch="TASK"> <xsl:elementname="li"> <xsl:text>Title: </xsl:text> <xsl:value-ofselect="@TITLE"/> <xsl:elementname="br"/> </xsl:element> <xsl:elementname="ul"> <xsl:apply-templatesselect="TASK"/> </xsl:element> </xsl:template>
只需添加& lt; ul>和& lt; li>在遍历树的代码中的正确位置。 使用XML文档匹配模板 TDLSS11看到文件。xsl和TDLSS12。xsl表示完整的示例。 通常,我们从根匹配模板开始,如示例文件TDLSS11.xsl中所示。 隐藏,复制Code
<xsl:templatematch="/TODOLIST"> <xsl:elementname="html"> <xsl:elementname="head"> <xsl:elementname="title"> <xsl:value-ofselect="@PROJECTNAME"/> </xsl:element> </xsl:element> <xsl:elementname="body"> <xsl:text>Root matching template</xsl:text> <xsl:elementname="br"/> <xsl:elementname="ul"> <xsl:apply-templatesselect="TASK"/> </xsl:element> </xsl:element> </xsl:element> </xsl:template>
但有时,需要从文档匹配模板开始,例如示例文件TDLSS12。xsl做同样的事情。 隐藏,复制Code
<xsl:templatematch="/"> <xsl:elementname="html"> <xsl:elementname="head"> <xsl:elementname="title"> <xsl:value-ofselect="@PROJECTNAME"/> </xsl:element> </xsl:element> <xsl:elementname="body"> <xsl:text>Document matching template</xsl:text> <xsl:elementname="br"/> <xsl:apply-templates/> </xsl:element> </xsl:element> </xsl:template> <xsl:templatematch="/TODOLIST"> <xsl:text>Root matching template</xsl:text> <xsl:elementname="br"/> <xsl:elementname="ul"> <xsl:apply-templatesselect="TASK"/> </xsl:element> </xsl:template>
您可以看到HTML文档内容总是在第一个被调用的模板中,而与文档匹配的模板将根作为子元素调用。 在样式表中包含HTML标记 当您想格式化输出时,最好使用html标记。 HTML根 一个html页面的根结构是这样的: 隐藏,复制Code
<html> <head> . . . </head> <body> . . . </body> </html>
由于它只在输出中出现一次,所以它必须在与根匹配的模板中。 隐藏,复制Code
<xsl:templatematch="/TODOLIST"> <xsl:elementname="html"> <xsl:elementname="head"> . . . </xsl:element> <xsl:elementname="body"> . . . <xsl:apply-templatesselect="TASK"/> . . . </xsl:element> </xsl:element> </xsl:template> </xsl:stylesheet>
参见文件TDLSS 3。xsl表示完整示例。 在HTML CRLF CRLF只在html源代码中使用,在页面的渲染中不做任何事情。必须使用标签代替。 隐藏,复制Code
<xsl:elementname="br"/>
并导致 隐藏,复制Code
<br/>
列表 html列表是通过缩进输出中的任务来显示任务嵌套的一种简单方法。这很容易,因为任务的嵌套与列表的嵌套相匹配。 一个html列表是由2部分: 列表分隔符一个列表线分隔符 列表分隔符环绕列表并在每个列表中出现一次。它自然位于处理父任务的模板中。 隐藏,复制Code
<xsl:elementname="ul"> <xsl:apply-templatesselect="TASK"/> </xsl:element>
每个列表项显示一次列表行分隔符。它自然位于处理子任务的模板中。 隐藏,复制Code
<xsl:elementname="li"> <xsl:text>Title: </xsl:text> <xsl:value-ofselect="@TITLE"/> <xsl:elementname="br"/> </xsl:element>
下载
zip包含示例文件: 文件bpsToDoListStyler_Rev018。xsl是todolist文件bpsToDoListStyler_Rev019文章中的示例文件。xsl是后面描述的正确文件。文件HelloWord。示例文件,参见snipset文件HelloTDL99。示例文件,参见snipset 链接 ToDoList-一种有效且灵活的保持方式:关于ToDoList软件的文章。ToDoList的XSL转换:在这篇文章中,我找到了一个用于ToDoList的示例样式表。AbstractSpoon软件ToDoList Wiki:由TDL作者制作的TDL Wiki页面。w3schools.com:一个教授XML、HTML、XSLT、XPath的网站。 历史 2015/05/01初稿。2015/05/19添加了一些东西,更新了下载和更正。2015/06/15增加更多素材,更新下载 本文转载于:http://www.diyabc.com/frontweb/news423.html