web-dev-qa-db-ja.com

PDFに改行を挿入FO <xsl:value-of>を使用して

XSL FOを生成するためにPDF情報を含むテーブルを含むファイルを使用しています。これらの列の1つは「説明」列です。文字列の例これらの説明フィールドの1つに次のように入力しています。

This is an example Description.<br/>List item 1<br/>List item 2<br/>List item 3<br/>List item 4

この説明に対応するテーブルセル内で、出力をそのように表示します。

This is an example Description.
List item 1
List item 2
List item 3
List item 4

他の場所を検索して、XSL FOを使用して、別の<fo:block></fo:block>要素内で<fo:block>を使用できることを確認しました。したがって、XMLを解析する前でも、私のXSLスタイルシートでは、<br/>のすべての出現箇所を<fo:block/>に置き換えるため、文字列のリテラル値は次のようになります。

This is an example Description.<fo:block/>List item 1<fo:block/>List item 2<fo:block/>List item 3<fo:block/>List item 4

この問題は、使用しているDescription文字列が<xsl:value-of>を使用して取得された場合に発生します。たとえば、次のようになります。

<fo:block>
    <xsl:value-of select="descriptionStr"/>
</fo:block>

この場合、my PDFドキュメントに出力される値はリテラル値であるため、すべての<fo:block/>リテラルを含む前の例とまったく同じです。手動で試してみました別の文字列の途中に<fo:block/>をハードコーディングすると、正しく表示されます。たとえば、スタイルシート内に次のように記述したとします。

<fo:block>Te<fo:block/>st</fo:block>

次のように正しく表示されます。

Te
st

ただし、<fo:block/><xsl:value-of select=""/>ステートメントの値の内部にある場合、これは発生しないようです。 SOやGoogleなどで検索してみましたが、役に立ちませんでした。助言や助けをいただければ幸いです。ありがとうございます。

23
Zkoh

xsl:value-of命令は使用しないでください。代わりにxsl:apply-templatesを使用してください。テキストノードの組み込みルールの場合、文字列値が出力されるだけで、空のbr要素の場合、ルールマッチングを宣言できますdescriptionStr/brまたはdescriptionStr//br(入力に応じて)空のfo:blockに変換します。

5
user357812

これは私を助け、最も単純な解決策になるはずです(Apache FOP 1.1での作業)。

<br/>行区切り記号と呼ばれるUnicode文字

   <xsl:template match="br">
      <xsl:value-of select="'&#x2028;'"/>
   </xsl:template>

参照 https://en.wikipedia.org/wiki/Newline#Unicode

8
j.per

次のコードは機能しました:

<fo:block white-space-collapse="false" 
    white-space-treatment="preserve" 
    font-size="0pt" line-height="15px">.</fo:block>

これにより、xslプロセッサは、このブロックに実際には0ptフォントサイズのテキスト行が含まれていると見なします。独自の値を指定して、行の高さをカスタマイズできます。

6
user2731517

エスケープされたXMLマークアップを含む文字列を生成することはめったに正しい答えではありませんが、それを扱う必要がある場合は、次のような入力を行います。

_<Description><![CDATA[This is an example Description.<br/>List item 1<br/>List item 2<br/>List item 3<br/>List item 4]]></Description>
_

xSLT 2.0を使用している場合は、_xsl:analyze-string_を使用して、本来必要な空の_fo:block_を取得できます。

_<xsl:template match="Description">
  <fo:block>
    <xsl:analyze-string select="." regex="&lt;br/>">
      <xsl:matching-substring>
        <fo:block />
      </xsl:matching-substring>
      <xsl:non-matching-substring>
        <xsl:value-of select="." />
      </xsl:non-matching-substring>
    </xsl:analyze-string>
  </fo:block>
</xsl:template>
_

xSLT 2.0を使用している場合は、@ Daniel Haleyのように_linefeed-treatment="preserve"_をより簡潔に使用し、replace()を使用して改行を挿入できます。

_<xsl:template match="Description">
  <fo:block linefeed-treatment="preserve">
    <xsl:value-of select="replace(., '&lt;br/>', '&#xA;')" />
  </fo:block>
</xsl:template>
_

XSLT 1.0を使用している場合は、文字列をたどって再帰できます。

_<xsl:template match="Description">
  <fo:block linefeed-treatment="preserve">
    <xsl:call-template name="replace-br" />
  </fo:block>
</xsl:template>

<xsl:template name="replace-br">
  <xsl:param name="text" select="." />

  <xsl:choose>
    <xsl:when test="not(contains($text, '&lt;br/>'))">
      <xsl:value-of select="$text" />
    </xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="substring-before($text, '&lt;br/>')"/>
      <xsl:text>&#xA;</xsl:text> <!-- or <fo:block /> -->
      <xsl:call-template name="replace-br">
        <xsl:with-param name="text" select="substring-after($text, '&lt;br/>')"/>
      </xsl:call-template>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>
_
2
Tony Graham

これを試して:

<fo:block><fo:inline color="transparent">x</fo:inline></fo:block>

このコードは、透明なテキストを含むブロックを追加し、新しい行のように見せます。

1
wymeric

新しい行に<br>ではなく、linefeed-treatment = "preserve"と\ nを使用してみてください。

<fo:block linefeed-treatment="preserve" >
 <xsl:value-of select="Description" />
</fo:block>
0
zongo

私は通常、多少のスペースが必要な場合に変更できる高さの空のブロックを使用します。

<fo:block padding-top="5mm" />

これが最善の解決策ではないことは知っていますが、機能的なものです。

0
indemidel

このようなテキストブロックがありました

<fo:table-cell display-align="right">
<fo:block font-size="40pt" text-align="right">
    <xsl:text> Text 1 </xsl:text>
    <fo:block> </fo:block>
    <xsl:text> Text2 </xsl:text>
    <fo:block> </fo:block>
    <xsl:text> Text 3</xsl:text>
</fo:block>

注意:空に注意してください

0
stingray_

XSLT 1.0の場合、GitHubで XSLT Line-Break Template を使用しています。

XSL-FOの場合、

  • 改行
  • 行区切り文字(対改行)
  • 行の一連のポインター
  • ポインターの繰り返しを無視する(連続した一連のポインターを無効にする)
  • 区切りまたは区切り文字を挿入するためのポインタとしての任意の文字列(デフォルトは "\ n")
  • 行区切り記号の高さ
  • 現在のフォントサイズからのデフォルトの行区切り記号の高さ。
  • 休憩場所を検索するときに「\ r」文字を自動的に無視します。
  • シームレスな移行のためのXSLT 2.0のサポートが追加されました。
  • 他の何か...

XSLT 2.0以降では、次のようなアプローチの使用を検討してください

  • XSLT 2.0 xsl:analyze-string(RegEx)
  • XPath 2.0トークン化+ XSLT(RegEx)
  • テンプレートパラメータとしてシーケンスを渡す(XSLT 2.0)
  • 等々
0
it3xl