XSLT - テンプレートから空白を削除する 質問する

XSLT - テンプレートから空白を削除する 質問する

私は XML を使用して小さな連絡先リストを保存しており、それを CSV ファイルに変換する XSL テンプレートを作成しようとしています。問題は出力内の空白です。

出力:

Friend, John, Smith, Home,
        123 test,
       Sebastopol,
       California,
       12345,
     Home 1-800-123-4567, Personal [email protected]

読みやすく開発しやすいように、ソース XML ファイルと関連する XSL テンプレートの両方にインデント/スペースを入れましたが、余分な空白がすべて出力に含まれてしまいます。XML 自体にはノード内に余分な空白はなく、書式設定のためにノードの外側にのみあります。XSLT についても同様です。

CSV ファイルを有効にするには、各エントリが分割されずに独自の行にある必要があります。XML と XSLT から余分な空白をすべて削除する (1 行の長いコードにする) 以外に、出力の空白を取り除く別の方法はありますか?

編集: ここに小さな XML サンプルがあります:

<PHONEBOOK>
    <LISTING>
        <FIRST>John</FIRST>
        <LAST>Smith</LAST>
        <ADDRESS TYPE="Home">
            <STREET>123 test</STREET>
            <CITY>Sebastopol</CITY>
            <STATE>California</STATE>
            <ZIP>12345</ZIP>
        </ADDRESS>
        <PHONE>1-800-123-4567</PHONE>
        <EMAIL>[email protected]</EMAIL>
        <RELATION>Friend</RELATION>
    </LISTING>
</PHONEBOOK>

XSLT は次のとおりです。

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />

 <xsl:template match="/">
   <xsl:for-each select="//LISTING">
    <xsl:value-of select="RELATION" /><xsl:text>, </xsl:text>
    <xsl:value-of select="FIRST" /><xsl:text>, </xsl:text>
    <xsl:value-of select="LAST" /><xsl:text>, </xsl:text>

    <xsl:if test="ADDRESS">
     <xsl:for-each select="ADDRESS">
       <xsl:choose>
        <xsl:when test="@TYPE">
         <xsl:value-of select="@TYPE" />,
        </xsl:when>
            <xsl:otherwise>
            <xsl:text>Home </xsl:text>
            </xsl:otherwise>
       </xsl:choose>
       <xsl:value-of select="STREET" />,
       <xsl:value-of select="CITY" />,
       <xsl:value-of select="STATE" />,
       <xsl:value-of select="ZIP" />,
     </xsl:for-each>
    </xsl:if>

    <xsl:for-each select="PHONE">
      <xsl:choose>
       <xsl:when test="@TYPE">
        <xsl:value-of select="@TYPE" />  
       </xsl:when>
       <xsl:otherwise><xsl:text>Home </xsl:text></xsl:otherwise>
      </xsl:choose>
     <xsl:value-of select="."  /><xsl:text  >, </xsl:text>
    </xsl:for-each>

    <xsl:if test="EMAIL">
     <xsl:for-each select="EMAIL">
      <xsl:choose>
       <xsl:when test="@TYPE">
        <xsl:value-of select="@TYPE" /><xsl:text  > </xsl:text> 
       </xsl:when>
       <xsl:otherwise><xsl:text  >Personal </xsl:text></xsl:otherwise>
      </xsl:choose>
      <xsl:value-of select="."  /><xsl:text  >, </xsl:text>
     </xsl:for-each>
    </xsl:if>
    <xsl:text>&#10;&#13;</xsl:text>
   </xsl:for-each>
 </xsl:template>

</xsl:stylesheet>

ベストアンサー1

XSLT では、空白は関連データである可能性が高いため、デフォルトで保持されます。

出力に不要な空白が入らないようにする最善の方法は、そもそも空白を作成しないことです。次のことはしないでください。

<xsl:template match="foo">
  foo
</xsl:template>

なぜなら、それは"\n··foo\n"プロセッサの観点からは、

<xsl:template match="foo">
  <xsl:text>foo</xsl:text>
</xsl:template>

スタイルシート内の空白は、XML 要素間にのみ存在する限り無視されます。簡単に言うと、XSLT コードのどこにも「裸の」テキストを使用せず、常に要素内に囲みます。

また、非特定的な表現を使うと、

<xsl:apply-templates />

テキスト ノードのデフォルトの XSLT ルールでは「出力にコピーする」とされているため、これは問題となります。これは「空白のみの」ノードにも適用されます。たとえば、次のようになります。

<xml>
  <data> value </data>
</xml>

3 つのテキスト ノードが含まれます。

  1. "\n··"(直後の<xml>
  2. "·value·"
  3. " \n"(直前</xml>

出力に #1 と #3 が紛れ込むのを回避するには (不要なスペースが発生する最も一般的な原因)、空のテンプレートを宣言してテキスト ノードのデフォルト ルールをオーバーライドします。

<xsl:template match="text()" />

すべてのテキスト ノードがミュートされ、テキスト出力を明示的に作成する必要があります。

<xsl:value-of select="data" />

値から空白を削除するには、normalize-space()XSLT 関数を使用できます。

<xsl:value-of select="normalize-space(data)" />

ただし、関数は文字列内にある空白を正規化するため、たとえば のよう"·value··1·"になるので注意してください"value·1"

さらに、<xsl:strip-space>および<xsl:preserve-space>要素を使用することもできますが、通常これは必要ありません (個人的には、上記のように明示的な空白処理を好みます)。

おすすめ記事