2

これは、docbook xml ファイルを処理するための XSLT ステートメントを作成するために知っておく必要がある一般的な XSLT 1.0 の質問です。私の docbook XML では、XSLT 1.0 で複合 xpath ステートメントを記述しようとしています。これは、HTML 出力の p タグの新しい属性「class = "play" をハードコードする」というものです。

これらの属性を持たないすべての タグに対してこのアクションを実行したい<para>

  1. role="normal-play-paragraph" AND
  2. role="no-indent" AND
  3. "role="ラインバース"

ここに私のXMLソースがあります:

<chapter xmlns="http://docbook.org/ns/docbook" 
 xmlns:xlink="http://www.w3.org/1999/xlink"
        version="5.0" xml:id="play">
  <title> Hamlet </title>

    <para role="no-indent"> SPHINX. Do you think about it very much?</para>
    <para role="normal-play-para"> INTERVIEWER. I do so say. </para>
    <para>SPHINX. Hello </para>
    <para> INTERVIEWER. dddddWhy I do so say. </para>
    <para> SPHINX. Yes. </para>
    <para role="line-verse"> Cosmologists have theorized or guessed</para>
</chapter>

Docbook XSLT が処理した後、HTML 出力を次のようにしたいと考えています。

<html>
<body>
<p class="no-indent">SPHINX. Do you think about it very much? much. </p>
 <p class="normal-play-para"> INTERVIEWER. I do so say. </p>
   <p class="play">SPHINX. Hello </p>
   <p class="play">INTERVIEWER. dddddWhy I do so say. </p>
   <p class="play">SPHINX. Yes.  </p>
 <p class="line-verse"> Cosmologists have theorized or guessed</p>
</body>
<html> 

docbook xslt には、実際に知る必要のない 2 つのメカニズムが機能しています。

まず、<para role="">elements で role の値を p の class に変更します。これがデフォルトの動作です。次に、特別なモードを使用して a"class='play'"を p タグにハードコードしています。

<xsl:template match="d:chapter[@xml:id = 'play']/d:para" mode="class.attribute" >
  <xsl:param name="class" select="local-name(.)"/>
  <xsl:attribute name="class">play</xsl:attribute>
</xsl:template>

ただし、他の属性と値が存在しない場合にのみ、 class="play" をハードコードする必要があります。上記のステートメントを変更して、属性 role="line-verse" を持つすべての para タグを除外できます。

  <xsl:template match="d:chapter[@xml:id = 'play']/d:para[@role != 'line-verse']" mode="class.attribute" >
    <xsl:param name="class" select="local-name(.)"/>
    <xsl:attribute name="class">play</xsl:attribute>
  </xsl:template>    

しかし、それ以上のものが必要です。role="line-verse" だけでなく、role="no-indent" と role="normal-play-para" も除外したい。

そのため、match 属性の xpath ステートメントの値を変更して、3 つの属性値を除外する必要があります。私はそれを行う方法を最もぼんやりと考えていません。誰か知っていますか?ありがとう。

回答に関する更新:

まず、私の質問を理解し、回答を作成するために時間を割いてくださったことに感謝します。私はまだこのことについては初心者であり、洗練された/複雑な Docbook XSL を使用しているため、私の質問は少し不公平でした。したがって、Docbook XSL スタイルシートと衝突しない答えが必要です。また、docbook xsl もインポートしていない場合、html 出力を生成する際に完全に有効な回答となる可能性のある変換を作成したことに気付きました。

ここで「最良」として選択した答えは、最も洗練されたものではないかもしれませんが、epub3 docbook-ns スタイルシートをインポートする場合にうまくいったものです。したがって、Rishe 氏の 1 行の回答は、それほどエレガントでなくても、実際に必要なことを正確に実行します。

私が始めたこのカスタマイズで何が起こっているのか本当にわかりません:

<xsl:template match="d:chapter[@xml:id = 'play']/d:para" mode="class.attribute" >
  <xsl:param name="class" select="local-name(.)"/>
  <xsl:attribute name="class">play</xsl:attribute>
</xsl:template>

私が知っているのは、ここにある a を呼び出しているということ<xsl:template name="generate.class.attribute">です。http://50.56.245.89/xsl-ns/xhtml-1_1/html.xsl

別物。Dimitre Novatchev の 2 つの回答は、うまくいくように見えます。ところで、 <xsl:param name="class" select="local-name(.)"/>ステートメントを含めるのを忘れていましたが、これは簡単に修正できますが、その解決策は有効です。

しかし、ディミトレ、私は別の質問があります。あなたが与えた2番目の答えは、シンプルで機能的に見える変数を使用していました。試してみると、Saxon 6.5 パーサーで検証エラーが発生します。(E [Saxon6.5.5] xsl:template の一致パターンには、変数への参照が含まれていない可能性があります)。多分それはタイプミスのような単純なものです。しかし、XSLT 1.0 テンプレートの一致で変数が許可されていない可能性はありますか?

4

2 に答える 2

2

これを試してみませんか:

<!-- Special handling for paras with one of the three roles -->
<xsl:template 
  match="d:chapter[@xml:id = 'play']/d:para[@role = 'line-verse' or @role = 'normal-play-para' or @role - 'line-indent']" 
  mode="class.attribute" >
  <xsl:attribute name="class">
      <xsl:value-of select="@role" />
  </xsl:attribute>
</xsl:template>

<!-- Other paras get the default class "play" -->
<xsl:template match="d:chapter[@xml:id = 'play']/d:para" mode="class.attribute">
  <xsl:attribute name="class">play</xsl:attribute>
</xsl:template>

さらに一歩進ん<xsl:attribute>で、これらのテンプレートを呼び出すテンプレートに を含め、class.attributeテンプレート自体に必要な値を含めるだけです。このようなもの:

<xsl:template match="d:chapter[@xml:id = 'play']/d:para">
    <p>
      <xsl:attribute name="class">
         <xsl:apply-templates select="." mode="class.attribute" />
      </xsl:attribute>
    ...
    </p>
</xsl:template>

<!-- Special handling for paras with one of the three roles -->
<xsl:template 
  match="d:chapter[@xml:id = 'play']/d:para[@role = 'line-verse' or @role = 'normal-play-para' or @role - 'line-indent']" 
  mode="class.attribute" >
      <xsl:value-of select="@role" />
</xsl:template>

<!-- Other paras get the default class "play" -->
<xsl:template match="d:chapter[@xml:id = 'play']/d:para" mode="class.attribute">
  <xsl:text>play</xsl:text>
</xsl:template>

元の質問に具体的に答えるために、これらの値のいずれも持たないparas に具体的に一致するテンプレートが本当に必要な場合は、次のXPath で一致させることができます。@role

d:chapter[@xml:id = 'play']/d:para[not(@role = 'line-verse' or @role = 'normal-play-para' or @role - 'line-indent')]

paraしかし、上で示したアプローチ (これらの役割を特別なケースとして扱い、その他すべてをデフォルトとして扱う) の方が良い方法だと思います。

于 2013-01-21T07:22:43.610 に答える
1

考えられる解決策の1つは次のとおりです。

  <xsl:template mode="class.attribute" match=
  "d:chapter[@xml:id = 'play']
       /d:para[not(@role = 'line-verse' 
                  or @role = 'no-indent' 
                  or @role = 'normal-play-para'
                   )]"  >
    <xsl:attribute name="class">play</xsl:attribute>
  </xsl:template>

ただし、「再生しない」値を簡単に変更できる、より柔軟で拡張可能なソリューションを使用します

 <xsl:param name="pNonPlayVals">
  <val>line-verse</val>
  <val>no-indent</val>
  <val>normal-play-para</val>
 </xsl:param>

  <xsl:template mode="class.attribute" match=
  "d:chapter[@xml:id = 'play']/d:para
         [not(@role = document('')/*/xsl:param[@name='pNonPlayVals']/val)]"  >
    <xsl:attribute name="class">play</xsl:attribute>
  </xsl:template>
于 2013-01-21T13:31:44.100 に答える