web-dev-qa-db-ja.com

xslを使用してプレーンテキストを出力する

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>

ここで私を助けてくれたいくつかの重要なこと:

  1. xsl:outputを使用して、出力ドキュメントの先頭にある標準宣言を省略する
  2. xml:space = "preserve"属性を使用して、xsl:for-eachタグ内に記述した空白を保持します。また、これには、for-eachタグ内のすべてのコードを、そのタグも含めて、1行で記述する必要がありました(改行を除く)。
  3. を使用して改行を挿入する-ここでも、標準のXMLインデントを省略する必要がありました。

このxsltの結果として望ましい出力は次のとおりです。

-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>
29
Chris
  • _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>
_
25
Mads Hansen

楽しみのために:これは非常に一般的でコンパクトな方法で行うことができます

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

この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>

必要な正しい結果が生成されます:

   at -f 09:33 05/05/2011 
   at -f 09:33 05/05/2011 
   at -f 09:33 05/05/2011  

:この一般的なアプローチは、出力されるすべてのデータが属性ではなくテキストノードに含まれている場合に最適です。

7