35

XML から単純なプレーン テキスト出力を生成するには、XSL を使用する必要がありました。オンラインで適切で簡潔な例が見つからなかったため、ここにソリューションを投稿することにしました。もちろん、より良い例を参照しているリンクは大歓迎です。

<?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
-f ggroup67 7:58 28.4.2010
-f ggroup70 15:58 18.4.2010
-f alluser 23:58 18.4.2010
-f ggroup61 7:58 22.9.2010
-f ggroup60 23:58 21.9.2010
で -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>
4

2 に答える 2

28
  • 一致するテンプレートを定義してscript/commandxsl:for-each
  • concat()<xsl:text>を使用して式を短縮し、多数のand<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>
于 2011-05-06T11:18:25.517 に答える
9

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

<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  

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

于 2011-05-06T13:24:12.820 に答える