xslt中template_在XSLT样式表中控制空白

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>

请注意,单个模板中的空白节点(例如主模板中的空白节点)已被删除,但是源文档中的节点(例如answertextline元素之间的节点)已保留。 处理这些问题有几种选择。

控制源中的空白

当处理器从一个元素中删除空白节点时,它首先检查该元素是否在保留空白元素的列表中。 默认情况下,所有源节点都添加到该列表中,但是您可以通过将它们添加到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:texttext元素始终保留,因此对于在文档中添加换行符或空格很有用:

清单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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值