3

XML を受け取り、適切にフォーマットされた XHTML を生成する既存の XSLT スタイルシートがあります。このスタイルシートの XSL-FO バージョンを作成して、Apache FOP 経由で PDF を生成したいと考えています。私が知りたいのはこれです:

次のようなことをするために学ぶ必要があるxsltパターンを使用するのに便利なものはありますか?

  • 一部のノードを変更せずにコピーする
  • ほとんどのノードをコピーしますが、追加の属性を追加します

を使用して新しいノードを作成できることを知っています

<xsl:element>

しかし、私が必要とする他の便利なものはありますか。ある XSLT フォーマットから別の XSLT フォーマットへのコピーはあまり行っていませんが、XSLT を介して大量の XML-> XHTML をコピーしたので、言語のコアのほとんどに精通していることに注意してください。

4

3 に答える 3

8

あなたが探しているパターンは、「変更された恒等変換」です。このアプローチの基礎は、以下のスタイルシートの最初のテンプレート ルールである恒等変換ルールです。その後の各ルールは、コピー動作の例外を表しています。

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- By default, copy all nodes unchanged -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- But strip out <foo> elements (including their content) -->
  <xsl:template match="foo"/>

  <!-- For <bar> elements, strip out start & end tags, but leave content --> 
  <xsl:template match="bar">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- For <bat> elements, insert an attribute and append a child --> 
  <xsl:template match="bat">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:attribute name="id">123</xsl:attribute>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

上記について私が最も不満に思っているのは、最後のテンプレート ルールで見つかったロジックの重複です。1 つの属性を追加するだけでも、これは大量のコードです。そして、これらの束が必要かどうか想像してみてください。オーバーライドしたいものをより外科的に正確にするための別のアプローチを次に示します。

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- By default, copy all nodes unchanged -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates mode="add-atts" select="."/>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

          <!-- By default, don't add any attributes -->
          <xsl:template mode="add-atts" match="*"/>

  <!-- For <bat> elements, insert an "id" attribute -->
  <xsl:template mode="add-atts" match="bat">
    <xsl:attribute name="id">123</xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

最後に、これは、実行したい編集の種類ごとに異なるモードを使用して、さらに進めることができます。

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- For <bat> elements, insert an "id" attribute -->
  <xsl:template mode="add-atts" match="bat">
    <xsl:attribute name="id">123</xsl:attribute>
  </xsl:template>

  <!-- Append <new-element/> to <bat> -->
  <xsl:template mode="append" match="bat">
    <new-element/>
  </xsl:template>

  <!-- Insert an element in <foo> content -->
  <xsl:template mode="insert" match="foo">
    <inserted/>
  </xsl:template>

  <!-- Add content before the <bar/> and <bat/> elements -->
  <xsl:template mode="before" match="bar | bat">
    <before-bat-and-bar/>
  </xsl:template>

  <!-- Add content only after <bat/> -->
  <xsl:template mode="after" match="bat">
    <after-bat/>
  </xsl:template>

  <!-- Here's the boilerplate code -->
  <!-- By default, copy all nodes unchanged -->
  <xsl:template match="@* | node()">
    <xsl:apply-templates mode="before" select="."/>
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates mode="add-atts" select="."/>
      <xsl:apply-templates mode="insert" select="."/>
      <xsl:apply-templates/>
      <xsl:apply-templates mode="append" select="."/>
    </xsl:copy>
    <xsl:apply-templates mode="after" select="."/>
  </xsl:template>

          <!-- By default, don't add anything -->
          <xsl:template mode="add-atts" match="*"/>
          <xsl:template mode="insert"   match="*"/>
          <xsl:template mode="append"   match="*"/>
          <xsl:template mode="before"   match="@* | node()"/>
          <xsl:template mode="after"    match="@* | node()"/>

</xsl:stylesheet>

XSLT 2.0 では、マルチモード テンプレート ルールのおかげで、ボイラープレートの一部を少し簡略化できます。

          <!-- By default, don't add anything -->
          <xsl:template mode="add-atts
                              insert
                              append
                              before
                              after" match="@* | node()"/>

これらすべてのカスタム モードを同じスタイルシートで使用することもありますが、多くの場合、必要に応じて遅延して追加します。

于 2009-06-05T17:15:51.047 に答える
0

以前、私は XSL-FO スタイルシートを開発し、Render-X FO2HTML スタイルシートを使用して XSL-FO を HTML に変換しました。<block>要素を、<div>などに変換します。<inline><span>

私は以前にそれらを使用したことはありませんが、HTML2FO スタイルシートを試してみることを検討してください。または、少なくともいくつかのアイデアを借りるためにそれらを調べます。

HTML には FO が提供するページ付け構造の一部が欠けているため、XSL-FO 出力に必要なものがすべて得られない可能性がありますが、HTML から XSL-FO 要素/属性への変換ロジックの大部分を処理できる可能性があります。ドキュメントの本文。

于 2009-08-21T11:50:20.110 に答える