xslt中template
注意:对于本技巧,您可以使用任何XSLT处理器(例如Xalan或Saxon),或基于浏览器的解决方案(例如Microsoft Internet Explorer或Mozilla)。
空格剥离规则
在处理转换之前,XSLT处理器将分析样式表和源文档,并删除所有适用的空白节点。 然后,它处理文档,并从其余节点构建结果树。
让我们看一个基本的转换。 源文档包含原始的FAQ信息,这些信息将转换为不同的XML结构,以供第二个应用程序处理:
清单1.源文档
<?xml version="1.0"?>
<?xml-stylesheet href="style.xsl" type="text/xsl"?>
<faqs>
<question>
<questiontitle>Output DOM object?</questiontitle>
<questiontext>
Is there an easy way to send a DOM Document to the screen?
<address>confused@wisconsin.com</address>
</questiontext>
<answer>
<answertext>
<line>Yes, as a matter of fact, there is. </line>
<line>All you have to do is transform the </line>
<line>Document, but don't add a style sheet:</line>
</answertext>
<codesection><codeline>...</codeline>
<codeline> DOMSource source = new DOMSource(myDocObject);</codeline>
<codeline> StreamResult result = new StreamResult(System.out);</codeline>
<codeline> TransformerFactory transFactory = </codeline>
<codeline> TransformerFactory.newInstance();</codeline>
<codeline> Transformer transformer = transFactory.newTransformer();</codeline>
<codeline> transformer.transform(source, result);</codeline>
<codeline>...</codeline></codesection>
</answer>
</question>
</faqs>
此转换的样式表旨在合并各个行,但最终将不得不在代码部分保留空白:
清单2.基本样式表
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<faqoutput>
<info>
<title>
<xsl:value-of select="faqs/question/questiontitle"/>
</title>
</info>
<xsl:apply-templates/>
</faqoutput>
</xsl:template>
<xsl:template match="question">
<issue><xsl:value-of select="questiontext"/></issue>
<solution><xsl:apply-templates select="answer"/></solution>
</xsl:template>
<xsl:template match="answertext">
<answered><xsl:apply-templates/></answered>
</xsl:template>
<xsl:template match="codesection">
<code>
<xsl:apply-templates/>
</code>
</xsl:template>
</xsl:stylesheet>
转换文档会显示空白剥离默认规则的结果:
清单3.结果集
<?xml version="1.0" encoding="UTF-8"?>
<faqoutput><info><title>Output DOM object?</title></info>
<issue>
Is there an easy way to send a DOM Document to the screen?
confused@wisconsin.com
</issue><solution>
<answered>
Yes, as a matter of fact, there is.
All you have to do is transform the
Document, but don't add a style sheet:
</answered>
<code>...
DOMSource source = new DOMSource(myDocObject);
StreamResult result = new StreamResult(System.out);
TransformerFactory transFactory =
TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.transform(source, result);
...</code>
</solution>
</faqoutput>
请注意,单个模板中的空白节点(例如主模板中的空白节点)已被删除,但是源文档中的节点(例如answertext
的line
元素之间的节点)已保留。 处理这些问题有几种选择。
控制源中的空白
当处理器从一个元素中删除空白节点时,它首先检查该元素是否在保留空白元素的列表中。 默认情况下,所有源节点都添加到该列表中,但是您可以通过将它们添加到xsl:strip-space
元素中来删除一个(或多个)节点。 例如,您可以从question
元素中剥离所有空白节点,以便压缩问题或答案文本内的所有响应:
清单4.剥离问题元素
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="question"/>
<xsl:template match="/">
<faqoutput>
<info>
<title>
...
如有必要,可以使用空格分隔的列表将更多元素名称添加到elements
属性。 这种相当蛮力的方法的结果是,所有空白节点都被剥离了:
清单5.剥离的结果:
<?xml version="1.0" encoding="UTF-8"?>
<faqoutput><info><title>Output DOM object?</title></info>
<issue>
Is there an easy way to send a DOM Document to the screen?
confused@wisconsin.com</issue><solution><answered>Yes, as a matter of fa
ct, there is. All you have to do is transform the Document, but don't add a styl
e sheet:</answered><code>... DOMSource source = new DOMSource(myDocObject); St
reamResult result = new StreamResult(System.out); TransformerFactory transFacto
ry = TransformerFactory.newInstance(); Transformer tra
nsformer = transFactory.newTransformer(); transformer.transform(source, result)
;...</code></solution>
</faqoutput>
您可能已经注意到,问题和address
元素的文本之间以及代码部分内仍存在空白。 这看起来可能令人困惑,但是请记住,我们正在剥离空白节点 ,而不是空白本身。 如果文本节点中除空格以外没有其他内容,则无论有何其他设置,处理器都不会将其删除。
另一方面,代码中的所有换行符现在都消失了,这是不希望的。 将元素从空白保留元素列表中删除后,可以使用xsl:preserve-space
元素将其后代之一添加回:
清单6.保留空白
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="question"/>
<xsl:preserve-space elements="codesection"/>
<xsl:template match="/">
<faqoutput>
<info>
...
更改的结果是将codesection
元素重新添加到保留空白元素的列表中,因此保留了换行符:
清单7.保存的结果:
<?xml version="1.0" encoding="UTF-8"?>
<faqoutput><info><title>Output DOM object?</title></info>
<issue>
Is there an easy way to send a DOM Document to the screen?
confused@wisconsin.com</issue><solution><answered>Yes, as a matter of fa
ct, there is. All you have to do is transform the Document, but don't add a styl
e sheet:</answered><code>...
DOMSource source = new DOMSource(myDocObject);
StreamResult result = new StreamResult(System.out);
TransformerFactory transFactory =
TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.transform(source, result);
...</code></solution>
</faqoutput>
但是,通过管理样式表中的空白,文档仍然可以更具可读性。
在样式表中添加空格
当处理器从样式表中删除空白节点时,默认情况下,空白保留元素列表中只有一个元素: xsl:text
。 text
元素始终保留,因此对于在文档中添加换行符或空格很有用:
清单8.使用xsl:text添加换行符:
...
<xsl:template match="question">
<issue><xsl:value-of select="questiontext"/></issue><xsl:text>
</xsl:text><solution><xsl:apply-templates select="answer"/></solution>
</xsl:template>
...
您可以使用xml:space
属性来分别控制将单个元素添加到保留空白元素的列表中,以及从该列表中删除单个元素:
清单9.用xml:space控制空格
...
<xsl:template match="/">
<faqoutput><xsl:text>
</xsl:text><info xml:space="preserve">
<title xml:space="default">
<xsl:value-of select="faqs/question/questiontitle"/>
</title>
</info>
<xsl:apply-templates/>
</faqoutput>
</xsl:template>
...
在这种情况下,结果是保留了title
元素周围的空白,而保留了title
元素内的空白。
清单10.在样式表中控制空白的结果:
<?xml version="1.0" encoding="UTF-8"?>
<faqoutput>
<info xml:space="preserve">
<title xml:space="default">Output DOM object?</title>
</info>
<issue>
Is there an easy way to send a DOM Document to the screen?
confused@wisconsin.com</issue>
<solution><answered>Yes, as a matter of fact, there is. All you have to do is
transform the Document, but don't add a style sheet:</answered><code>...
DOMSource source = new DOMSource(myDocObject);
StreamResult result = new StreamResult(System.out);
TransformerFactory transFactory =
TransformerFactory.newInstance();
Transformer transformer = transFactory.newTransformer();
transformer.transform(source, result);
...</code></solution>
</faqoutput>
摘要
通过了解应用于样式表或源文档的空白保留规则,您可以紧密控制最终文档的外观,但是绝不会在文本节点内剥离空白。
翻译自: https://www.ibm.com/developerworks/xml/library/x-tipwhitesp/index.html
xslt中template