0

この質問をもう一度申し訳ありません。前の質問の回答を使用しているときに問題が発生しました。私のxmlが次のようになっているとします。

<comp>
<section id="1">
 <p>text</p>
 <figure xml:id="c1-fig-002"/>
 <p>text</p>
 <figure xml:id="c1-fig-003"/>
</section>
<section id="2">
 <p>text</p>
 <figure xml:id="c1-fig-003"/>
 <figure xml:id="c1-fig-004" resumeNumberingAt="7"/>
 <figure xml:id="c1-fig-005"/>
 <p>text</p>
</section>
<section id="3">
 <p>text</p>
 <figure xml:id="c1-fig-006"/>
 <figure xml:id="c1-fig-007" resumeNumberingAt="18"/>
 <p>text</p>
 <figure xml:id="c1-fig-008"/>
 <p>text</p>
 <figure xml:id="c1-fig-009"/>
</section>
</comp>

次の結果を得るために xslt を使用しています。

<comp>
<section id="1">
 <p>text</p>
 <figure xml:id="c1-fig-002"/>
 <fignum>2</fignum>
 <p>text</p>
 <figure xml:id="c1-fig-003"/>
 <fignum>3</fignum>
</section>
<section id="2">
 <p>text</p>
 <figure xml:id="c1-fig-003"/>
 <fignum>3</fignum>
 <figure xml:id="c1-fig-004" resumeNumberingAt="7"/>
 <fignum>7</fignum>
 <figure xml:id="c1-fig-005"/>
 <fignum>8</fignum>
 <p>text</p>
</section>
<section id="3">
 <p>text</p>
 <figure xml:id="c1-fig-006"/>
 <fignum>9</fignum>
 <figure xml:id="c1-fig-007" resumeNumberingAt="18"/>
 <fignum>18</fignum>
 <p>text</p>
 <figure xml:id="c1-fig-008"/>
 <fignum>19</fignum>
 <p>text</p>
 <figure xml:id="c1-fig-009"/>
 <fignum>20</fignum>
</section>
</comp>

2からの図の後に来る数値から値を取得する必要がありますc1-fig-002

属性 resumeNumberingAt がある場合、通常の値の代わりにその値を使用し、次のノードの値をインクリメントする必要があります。これを行うために次の xslt を使用しましたが、機能していません。

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

  <xsl:template match="figure[@resumeNumberingAt != '']">
    <xsl:call-template name="fig">
      <xsl:with-param name="sequence" select="@resumeNumberingAt"/>
    </xsl:call-template>
  </xsl:template>

  <xsl:template match ="section">
   <!--some operation-->
  </xsl:template>
  <xsl:template match ="p">
  <!--some operation-->
  </xsl:template>
  <xsl:template match="figure" name="fig">
    <xsl:param name="sequence" select="substring(@xml:id, 10, 1)"/>
    <figure>
      <xsl:apply-templates select="@*"/>
      <fignum>
        <xsl:value-of select="$sequence"/>
      </fignum>
    </figure>
    <xsl:apply-templates select="following-sibling::figure[1]">
      <xsl:with-param name="sequence" select="$sequence + 1"/>
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>
4

1 に答える 1

1

このXSLT1.0スタイルシート...

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />  
  
<xsl:template match="@*|node()">
 <xsl:copy>
  <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
</xsl:template>
  
<xsl:template match="figure">
 <xsl:copy>
  <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
 <fignum>
   <xsl:variable name="base-node" select="
     ((preceding::figure[@resumeNumberingAt] |
       self     ::figure[@resumeNumberingAt] )[last()]  |
       self     ::figure)[1]" />
   <xsl:variable name="base">
     <xsl:apply-templates select="$base-node" mode="numbering" />
   </xsl:variable>
   <xsl:variable name="prev-figs"      select="preceding::figure" />
   <xsl:variable name="prev-fig-count" select="count($prev-figs)" />
   <xsl:value-of select="$base +
     count(($base-node/following::figure|$base-node)
       [count(. | $prev-figs) = $prev-fig-count])" />
 </fignum> 
</xsl:template>

<xsl:template match="figure[@resumeNumberingAt]" mode="numbering">
 <xsl:value-of select="@resumeNumberingAt" /> 
</xsl:template>
  
<xsl:template match="figure" mode="numbering">
 <xsl:value-of select="substring(@xml:id, 8, 3)" /> 
</xsl:template>
  
</xsl:stylesheet>

...サンプルの入力ドキュメントを取得し、指定された期待される出力ドキュメントを生成します。このソリューションは、MicrosoftXslCompiledTransformXSLTエンジンで正常にテストされました。

説明

モードのないfigureテンプレートでは、入力されたfigure要素をコピーして、次のfignum要素を作成します。変数$base-nodeは、Figure番号のベースとなるベースノードになります。詳細を見ると、この表現は...

(preceding::figure[@resumeNumberingAt] |
 self     ::figure[@resumeNumberingAt] )[last()]

... @resumeNumberingAt属性を持つ最も近い前のFigure要素、またはこれが@resumeNumberingAt属性を持っている場合はこれ(フォーカスノード)を参照します。一般的に、これはfignumを数えるためのベースになります。ただし、例外は、フォーカスノードが最初の@resumeNumberingAtの前にある場合です。この場合、(xml:id属性を介して)コンテキストノードのカウントをベースにします。したがって、すべての場合において、この式を使用した厄介なxsl:ifステートメントなしでベースノードを見つけることができます。

 ((preceding::figure[@resumeNumberingAt] |
   self     ::figure[@resumeNumberingAt] )[last()]  |
   self     ::figure)[1]

次に、ベース番号を計算します。ベースノードがあります。@resumeNumberingAt属性がある場合はそれがベース番号であり、そうでない場合は@xml:id属性に基づいています。明示的なテストを行うのではなく、モードを使用してテンプレート選択メカニズムを利用するだけで、ベース番号を計算できます。たとえば、ノードの場合...

<figure xml:id="c1-fig-006"/>

...ベースノードは...

<figure xml:id="c1-fig-004" resumeNumberingAt="7"/>

...したがって、基数は7です。必要なfignumを9にするには、後でこれを+2オフセットする必要があります。対照的に、ノードの場合...

<figure xml:id="c1-fig-003"/>

...ベースノードはそれ自体であり、ベース値は3です(「003」は整数に変換されます)。後で必要なfignum3を取得するには、これを+0でオフセットする必要があります。

変数$prev-figsは、この前のFigure要素のセットです。そこで、ベースノードとフォーカスノード(ベースノードを含むがフォーカスノードを除く)の間の数字の数でベースfignumをオフセットすることにより、fignumを計算します。このオフセットは、2つのセット間の共通部分です。

(1)ベースノードに続く(および含む)図。と

(2)フォーカスノードの前の図。

XSLT 1.0では、2つのセットの共通部分を計算するための一般的な方法は...

$node-set1[count(. | $node-set2) = count($node-set2)]

...そしてそれはまさに私たちがこの命令で行うことです...

<xsl:value-of select="$base +
 count(($base-node/following::figure|$base-node)
   [count(. | $prev-figs) = $prev-fig-count])" />

一般原理

次の一般原則が採用されました。

  1. 明示的な分岐命令を回避するには、和集合演算子(|)と位置述語を使用します。
  2. テンプレートマッチングメカニズムを使用して、明示的な分岐命令を回避し、パワー、拡張性、およびシンプルさを提供します。
  3. 必要に応じて、XSLT1.0セット交差のパターンを使用します。
于 2012-08-01T13:34:23.523 に答える