web-dev-qa-db-ja.com

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

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

185
Mithil

次のXSLコードは、 改行 (改行)文字を生成します。

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

キャリッジリターン の場合、次を使用します。

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

これを行うための私のお気に入りの方法は次のようになります:

<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を出力するときに、この手法を使用しました。実際、コンマ、引用符、改行の変数を作成する傾向があります。

48
Nic Gibson

Xsl:outputタグに属性Method = "text"を含め、適切なポイントでXSLのリテラルコンテンツに改行を含めます。 XSLのソースコードを整理する場合は、新しい行が必要なエンティティ&#10;を使用します。

45
AnthonyWJones

使用できます:<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>

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

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

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

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

  1. HTMLマークアップには改行はありません。単純な<br/>を使用すると問題ありません。そうしないと、空白が表示されます。ブラウザからソースを表示すると、実際に何が起こったのかがわかります。ただし、特に消費者が直接ブラウザでない場合は、この動作を期待する場合があります。たとえば、HTMLページを作成し、その構造をブラウザに提供する前に、空の行とIDで適切にフォーマットされた状態で表示する必要があります。
  2. disable-output-escapingを使用する必要がある場所と使用しない場所を覚えておいてください。別のxmlから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. nlnl=lf)ではなく、crlfについて話していることを忘れないでください。私の最初の試みはcr:&#xdのみを使用することであり、出力xmlはDOMによって適切に検証されました。

破損したxmlを表示していました。

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

DOMパーサーは制御文字を無視しましたが、レンダリングはしませんでした。私はこれを見ていることがどれほど愚かであるかを理解するまで、かなりの時間を頭にぶつけました!

記録のために、どこでも動作することを100%確実にするために、両方のCRLFで本体内の変数を使用します。

5
Agoun

ここに表示される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>タグ内に配置されます。

3
Sam Harwell

私の経験から、新しい行INSIDE a <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>ノード)に入れようとしたものは何も機能しませんでした(このページのより単純な提案のほとんどを含む)。私はそれを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
ShayLivyatan

あなたが試すことができます、

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

それが動作します。

2

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

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

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

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

2
Agnes

Nic Gibsonの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>
1

XSLTを使用してXMLファイルをフォーマットすると、エンティティが消えるため、<xsl:text>&#xa;</xsl:text>アプローチを使用できませんでした。だから、変数を使用したアプローチについてもう少しラウンドを使用する必要がありました

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