XSLTで新しいラインを作成する


198

XSLTでテキスト出力用の改行を生成したい。何か案は?


11
答えを受け入れる時が
来たと思い

回答:


240

次のXSLコードは、改行(ラインフィード)文字を生成します

<xsl:text>&#xa;</xsl:text>

以下のためのキャリッジリターンは、次を使用します。

<xsl:text>&#xd;</xsl:text>

7
+1:これは<xsl:text>、XSLファイルを再フォーマットする可能性のあるものを使用して空白で混乱させる場合、改行を含むアプローチよりも堅牢です。
イアンロバーツ

49

これを行うための私の好まれる方法は次のようになります。

<xsl:stylesheet>

<xsl:output method='text'/>

<xsl:variable name='newline'><xsl:text>
</xsl:text></xsl:variable>

<!-- note that the layout there is deliberate -->

...

</xsl:stylesheet>

次に、改行(おそらくcsvの場合)を出力するときはいつでも、次のような出力を行うことができます。

<xsl:value-of select="concat(elem1,elem2,elem3,$newline)" />

xml入力からsqlを出力するときにこのテクニックを使用しました。実際、コンマ、引用符、改行の変数を作成する傾向があります。


3
以下のフロージョンの答えは私のものよりかなり安定していることに注意してください。
ニックギブソン

1
おそらく、安定性を高めるxml:space="preserve"ためにxsl:text要素に宣言を追加する価値がありますが、@ Florjonの答えがおそらくより安全であることには同意します。
Flynn1179 14

この解決策には、望ましくない可能性のあるインデントも含まれるという欠点があります。
wmassingham 2015

47

属性Method = "text"をxsl:outputタグに含め、改行をXSLのリテラルコンテンツの適切なポイントに含めます。XSLのソースコードを整頓し&#10;たい場合は、改行したいエンティティを使用してください。


31

以下を使用できます。 <xsl:text>&#10;</xsl:text>

例を見る

<xsl:variable name="module-info">
  <xsl:value-of select="@name" /> = <xsl:value-of select="@rev" />
  <xsl:text>&#10;</xsl:text>
</xsl:variable>

これをファイルに書き込むと、たとえば

<redirect:write file="temp.prop" append="true">
  <xsl:value-of select="$module-info" />
</redirect:write>

この変数は、次のように新しいファイルinfileを生成します。

commons-dbcp_commons-dbcp = 1.2.2
junit_junit = 4.4
org.easymock_easymock = 2.4

6

私見@Florjonが提供した以上の情報は必要ありません。たぶんそれが時々私たちにとってうまくいかないかもしれない理由を理解するためにいくつかの小さな詳細が残っているかもしれません。

まず、a内の&#xa(hex)または&#10(dec)<xsl:text/>は常に機能しますが、表示されない場合があります。

  1. HTMLマークアップに改行はありません。シンプルなもの<br/>を使用するとうまくいきます。それ以外の場合は、空白が表示されます。ブラウザからソースを表示すると、実際に何が起こったかがわかります。ただし、特に消費者が直接ブラウザでない場合は、この動作を期待する場合があります。たとえば、HTMLページを作成して、ブラウザに提供する前に、空の行とIDで適切にフォーマットされた構造を表示するとします。
  2. 使用する必要がある場所と使用しない場所を覚えておいてくださいdisable-output-escaping。別のXMLを作成し、そのDTDをスタイルシートから宣言する必要がある次の例を見てみましょう。

最初のバージョンは文字をエスケープします(xsl:textのデフォルト)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" encoding="utf-8"/>

    <xsl:template match="/">
        <xsl:text>&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>
        <xsl:copy>
            <xsl:apply-templates select="*" mode="copy"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="@*|node()" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" mode="copy"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

そしてここに結果があります:

<?xml version="1.0" encoding="utf-8"?>
&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;

&#13;<Subscriptions>
    <User id="1"/>   
</Subscriptions>

OK、それは私たちが期待することを行い、エスケープは使用した文字が適切に表示されるように行われます。ルートノード内のXML部分のフォーマットは、によって処理されident="yes"ます。しかし、よく見ると、改行文字&#xaがそのままエスケープおよび変換されておらず、二重改行が実行されていることがわかります。これについての説明はありませんが、知っておくと良いでしょう。誰でも?

2番目のバージョンは文字をエスケープしないため、意図したとおりの文字を生成しています。行われた変更は次のとおりです。

<xsl:text disable-output-escaping="yes">&lt;!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd"&gt;&#xa;&#xa;&#xd;</xsl:text>

そしてここに結果があります:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Subscriptions SYSTEM "Subscriptions.dtd">

<Subscriptions>
    <User id="1"/>   
</Subscriptions>

そしてそれは大丈夫でしょう。crとlfの両方が適切にレンダリングされます。

  1. ()nlではなく、について話していることを忘れないでください。私の最初の試みはcr:のみを使用することでしたが、出力xmlはDOMによって適切に検証されました。crlfnl=lf&#xd

破損したxmlを表示していた:

<?xml version="1.0" encoding="utf-8"?>
<Subscriptions>riptions SYSTEM "Subscriptions.dtd">
    <User id="1"/>   
</Subscriptions>

DOMパーサーは制御文字を無視しましたが、レンダリングされませんでした。頭がおかしくなるのにかなり時間がかかりました。

記録のために、私は両方のCRLFで本体内の変数を使用しています。


4

DOCTYPEここに表示されるディレクティブを追加しました:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
  <!ENTITY nl "&#xa;">
]>
<xsl:stylesheet xmlns:x="http://www.w3.org/2005/02/query-test-XQTSCatalog"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="2.0">

これにより、出力に改行を生成する&nl;代わりにを使用でき&#xa;ます。他のソリューションと同様に、これは通常<xsl:text>タグ内に配置されます。



2

私はニックギブソンの方法の2番目です。これは常に私のお気に入りでした。

<xsl:variable name='nl'><xsl:text>
</xsl:text></xsl:variable>

ただし、Antタスク<echoxml>を使用してスタイルシートを作成し、ファイルに対して実行しています。タスクは$ {DSTAMP}などの属性値テンプレートを実行しますが、XMLを再フォーマットするため、場合によってはエンティティ参照が適しています。

<xsl:variable name='nl'><xsl:text>&#xa;</xsl:text></xsl:variable>

3
変数を使用する場合は、のselect代わりに使用することをお勧めしますxsl:text。例:<xsl:variable name="nl" select="'&#xA;'"/>このようにして、不要なRTF(結果ツリーフラグメント)を作成しません。
Daniel Haley

2

<xsl:text>使用し&#xA;たリテラル改行とリテラル改行の違いを発見しました。

(SaxonとデフォルトのJava XSLTプロセッサーの両方を使用する)私の環境ではリテラルの改行が正常に機能しましたが、.NET環境で実行されている別のグループによってコードが実行されると、コードが失敗しました。

エンティティ(&#xA;)に変更すると、ファイル生成コードがJavaと.NETの両方で一貫して実行されます。

また、文字どおりの改行はIDEによる再フォーマットに対して脆弱であり、「知らない」誰かがファイルを管理していると、誤って失われる可能性があります。


2

私は、新しいライン生産というのが私の経験から気づいたINSIDE<xsl:variable>句は仕事をしません。私は次のようなことをやろうとしました:

<xsl:variable name="myVar">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My value: </xsl:text>
      <xsl:value-of select="@myValue" />
      <xsl:text></xsl:text> <!--NEW LINE-->
      <xsl:text>My other value: </xsl:text>
      <xsl:value-of select="@myOtherValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

<div>
  <xsl:value-of select="$myVar"/>
</div>

その「新しい行」(空の<xsl:text>ノード)に入れようとしたことは、(このページの簡単な提案のほとんどを含めて)機能せず、HTMLがそこで機能しないという事実は言うまでもありません。それを2つの変数に分割し、<xsl:variable>スコープの外でそれらを呼び出して、それらの<br/>間にシンプルを置く必要がありました:

<xsl:variable name="myVar1">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My value: </xsl:text>
      <xsl:value-of select="@myValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

<xsl:variable name="myVar2">
  <xsl:choose>
    <xsl:when test="@myValue != ''">
      <xsl:text>My other value: </xsl:text>
      <xsl:value-of select="@myOtherValue" />
    </xsl:when>
  </xsl:choose>
<xsl:variable>

<div>
  <xsl:value-of select="$myVar1"/>
  <br/>
  <xsl:value-of select="$myVar2"/>
</div>

ええ、私は知っています。これは最も洗練されたソリューションではありませんが、私の欲求不満の経験をXSLと共有するだけで機能します;)


2

<xsl:text>&#xa;</xsl:text>XSLTを使用してXMLファイルをフォーマットするとエンティティが表示されなくなるため、この方法を使用できませんでした。だから私は変数を使用するアプローチをもう少しラウンドする必要がありました

<xsl:variable name="nl" select="'&#10;'"/>
<xsl:template match="/">
    <xsl:value-of select="$nl" disable-output-escaping="no"/>
    <xsl:apply-templates select="*"/>
</xsl:template>

-4

このタグを追加するだけです:

<br/>

わたしにはできる ;) 。


7
問題はテキスト出力についてです。このソリューションは、出力がHTMLとしてレンダリングされた場合にのみ機能します。
2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.