使用xsl输出纯文本

Chr*_*ris 29 xml xslt foreach line-breaks plaintext

我需要使用XSL从XML生成简单的纯文本输出.由于我没有在网上找到任何好的,简洁的例子,我决定在这里发布我的解决方案.任何指向更好的例子的链接当然会受到赞赏:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" >
    <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
    <xsl:template match="/">
        <xsl:for-each select="script/command" xml:space="preserve">at -f <xsl:value-of select="username"/> <xsl:value-of select="startTime/@hours"/>:<xsl:value-of select="startTime/@minutes"/> <xsl:value-of select="startDate"/><xsl:text>
</xsl:text></xsl:for-each> 
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

一些帮助我的重要事情:

  1. 使用xsl:output省略输出文档开头的标准声明
  2. 使用xml:space ="preserve"属性来保存我在xsl:for-each标记中写的任何空格.这也要求我在for-each标签中编写所有代码,包括该标签,在一行上(除了换行符).
  3. 使用插入换行符 - 再次我不得不在这里省略标准的xml缩进.

此xslt的结果和所需输出为:

at -f alluser 23:58 17.4.2010
at -f ggroup67 7:58 28.4.2010
at -f ggroup70 15:58 18.4.2010
at -f alluser 23:58 18.4.2010
at -f ggroup61 7:58 22.9.2010
at -f ggroup60 23:58
21.9.2010 at -f alluser 3:58 22.9.2010

正如我所说,任何有关如何更优雅地做到这一点的建议将不胜感激.


后续行动2011-05-08:

这是我正在处理的xml的类型:

<script xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="script.xsd">
    <command>
        <username>alluser</username>
        <startTime minutes="58" hours="23"/>
        <startDate>17.4.2010</startDate>
    </command>
</script>
Run Code Online (Sandbox Code Playgroud)

Mad*_*sen 25

  • 您可以定义模板以匹配script/command并消除xsl:for-each
  • concat()可以用来缩短表达式,避免显式插入这么多<xsl:text><xsl:value-of>元素.
  • 使用实体引用&#xA;的回车,而不是依靠保护你的断行<xsl:text>元素更安全一点,因为代码格式化不会弄乱你的换行符.此外,对我来说,它作为一个明确的换行符读取,更容易理解意图.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:fo="http://www.w3.org/1999/XSL/Format" >
    <xsl:output method="text" omit-xml-declaration="yes" indent="no"/>

    <xsl:template match="script/command">
        <xsl:value-of select="concat('at -f '
                    ,username
                    ,' '
                    ,startTime/@hours
                    ,':'
                    ,startTime/@minutes
                    ,' '
                    ,startDate
                    ,'&#xA;')"/>
    </xsl:template>

</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)


Dim*_*hev 7

只是为了好玩:这可以通过非常通用和紧凑的方式完成:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="*">
        <xsl:apply-templates select="node()|@*"/>
        <xsl:text> </xsl:text>
    </xsl:template>

    <xsl:template match="username">
       at -f <xsl:apply-templates select="*|@*"/>
    </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

应用于此XML文档时:

<script>
 <command>
  <username>John</username>
  <startTime hours="09:" minutes="33"/>
  <startDate>05/05/2011</startDate>

  <username>Kate</username>
  <startTime hours="09:" minutes="33"/>
  <startDate>05/05/2011</startDate>

  <username>Peter</username>
  <startTime hours="09:" minutes="33"/>
  <startDate>05/05/2011</startDate>
 </command>
</script>
Run Code Online (Sandbox Code Playgroud)

产生了想要的正确结果:

   at -f 09:33 05/05/2011 
   at -f 09:33 05/05/2011 
   at -f 09:33 05/05/2011  
Run Code Online (Sandbox Code Playgroud)

注意:如果要输出的所有数据都包含在文本节点中(而不是属性中),则此genaral方法最适用.