1

属性に基づいてxsltの値をインクリメントする必要があります。私のxmlがこのようになっているとしましょう。

   <comp>
   <fig xml:id="c1-fig-001"/>
   <fig xml:id="c1-fig-002"/>
   <fig xml:id="c1-fig-003"/>
   <fig xml:id="c1-fig-004" resumeatnum="7"/>
   <fig xml:id="c1-fig-005"/>
   <fig xml:id="c1-fig-006"/>
   <fig xml:id="c1-fig-007" resumeatnum="18"/>
   <fig xml:id="c1-fig-008"/>
   <fig xml:id="c1-fig-009"/>
   </comp>

このような出力が必要です、

<comp>
<fig xml:id="c1-fig-001"/>
<fignum>1.1</fignum>
<fig xml:id="c1-fig-002"/>
<fignum>1.2</fignum>
<fig xml:id="c1-fig-003"/>
<fignum>1.3</fignum>
<fig xml:id="c1-fig-004" resumeatnum="7"/>
<fignum>1.7</fignum>
<fig xml:id="c1-fig-005"/>
<fignum>1.8</fignum>
<fig xml:id="c1-fig-006"/>
<fignum>1.9</fignum>
<fig xml:id="c1-fig-007" resumeatnum="18"/>
<fignum>1.18</fignum>
<fig xml:id="c1-fig-008"/>
<fignum>1.19</fignum>
<fig xml:id="c1-fig-009"/>
<fignum>1.20</fignum>
</comp>

xml:idfromのような属性から値を取得1c1、後に続く番号から別の番号を取得する必要がありますfig

属性がある場合resumeatnumは、通常の値の代わりにその値を使用して、次のノードの値をインクリメントする必要があります。これを行うためにxsltを提供してください。

4

5 に答える 5

1

次のXSLT2.0スタイルシート:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  exclude-result-prefixes="xs" 
  version="2.0">

  <xsl:template match="comp">
    <xsl:for-each-group select="fig" group-starting-with="*[@resumeatnum]">
      <xsl:variable name="base" select="(@resumeatnum, 1)[1] - 1"/>
      <xsl:for-each select="current-group()">
        <xsl:copy-of select="."/>
        <fignum>1.<xsl:value-of select="position()+$base"/></fignum>
      </xsl:for-each>
    </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>

次の出力を生成します。

<?xml version="1.0" encoding="UTF-8"?>
<fig xml:id="c1-fig-001"/>
<fignum>1.1</fignum>
<fig xml:id="c1-fig-002"/>
<fignum>1.2</fignum>
<fig xml:id="c1-fig-003"/>
<fignum>1.3</fignum>
<fig xml:id="c1-fig-004" resumeatnum="7"/>
<fignum>1.7</fignum>
<fig xml:id="c1-fig-005"/>
<fignum>1.8</fignum>
<fig xml:id="c1-fig-006"/>
<fignum>1.9</fignum>
<fig xml:id="c1-fig-007" resumeatnum="18"/>
<fignum>1.18</fignum>
<fig xml:id="c1-fig-008"/>
<fignum>1.19</fignum>
<fig xml:id="c1-fig-009"/>
<fignum>1.20</fignum>
于 2012-07-26T22:35:19.747 に答える
1

これは、より短く(33の適切にフォーマットされた短い行)、より単純なXSLT 1.0ソリューション(3つの短いテンプレート、no substring()、no substring-before()、複雑で長い複数行の式、no concat()、no xsl:for-each、no xsl:if、no xsl:variable、no string-length()、noxsl:call-template

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

 <xsl:key name="kFollowing" match="fig[not(@resumeatnum)]"
      use="generate-id((preceding-sibling::*[@resumeatnum][1]
                      |
                        ..
                        )[last()]
                      )"/>

 <xsl:template match="/*">
  <comp>
   <xsl:apply-templates select="key('kFollowing', generate-id())"/>
   <xsl:apply-templates select="fig[@resumeatnum]"/>
  </comp>
 </xsl:template>

 <xsl:template match="fig">
  <xsl:param name="pStart" select="1"/>

  <fig xml:id="{@xml:id}"/>
   <fignum>1.<xsl:value-of select="position() + $pStart -1"/></fignum>
 </xsl:template>

 <xsl:template match="fig[@resumeatnum]">
   <fig xml:id="{@xml:id}" resumeatnum="{@resumeatnum}"/>
   <fignum>1.<xsl:value-of select="@resumeatnum"/></fignum>
  <xsl:apply-templates select="key('kFollowing', generate-id())">
   <xsl:with-param name="pStart" select="@resumeatnum+1"/>
  </xsl:apply-templates>
 </xsl:template>
</xsl:stylesheet>

提供されたXMLドキュメントに適用する場合:

<comp>
    <fig xml:id="c1-fig-001"/>
    <fig xml:id="c1-fig-002"/>
    <fig xml:id="c1-fig-003"/>
    <fig xml:id="c1-fig-004" resumeatnum="7"/>
    <fig xml:id="c1-fig-005"/>
    <fig xml:id="c1-fig-006"/>
    <fig xml:id="c1-fig-007" resumeatnum="18"/>
    <fig xml:id="c1-fig-008"/>
    <fig xml:id="c1-fig-009"/>
</comp>

必要な正しい結果が生成されます:

<comp>
   <fig xml:id="c1-fig-001"/>
   <fignum>1.1</fignum>
   <fig xml:id="c1-fig-002"/>
   <fignum>1.2</fignum>
   <fig xml:id="c1-fig-003"/>
   <fignum>1.3</fignum>
   <fig xml:id="c1-fig-004" resumeatnum="7"/>
   <fignum>1.7</fignum>
   <fig xml:id="c1-fig-005"/>
   <fignum>1.8</fignum>
   <fig xml:id="c1-fig-006"/>
   <fignum>1.9</fignum>
   <fig xml:id="c1-fig-007" resumeatnum="18"/>
   <fignum>1.18</fignum>
   <fig xml:id="c1-fig-008"/>
   <fignum>1.19</fignum>
   <fig xml:id="c1-fig-009"/>
   <fignum>1.20</fignum>
</comp>
于 2012-07-27T04:42:33.400 に答える
0

このようなものが機能する可能性があります

<xsl:for-each select="/comp/fig">
    <fignum>1.<xsl:value-of select="substring(@xml:id,string-length(@xml:id),1)"/>1</fignum>
</xsl:for-each>

しばらくxslt/xpathを使用していないため、完全ではない可能性があります。基本的には、figノードをループして、最後の文字をサブストリングします。ループするノードが9つを超える場合は、サブストリングを変更してすべての数字を取得する必要があります

于 2012-07-26T16:56:22.817 に答える
0

PigChicken、彼は以前の[存在する場合]resumeatnum属性に基づいて自動インクリメント機能を変更するものを求めていたと思います。以下は、メジャーバージョンとマイナーバージョンのコンポーネントの変数を作成し、履歴書から対応するマイナーバージョンに「オフセット」を追加することで、特定の例に対して完全に機能します。たとえば、resumeatnumが18で、マイナーバージョンが7の場合、オフセットは11になります。これは、次のマイナーバージョンにも追加されます。number()キャストを利用しましたが、一部削除される可能性があります。変換は次のとおりです。

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.1" exclude-result-prefixes="" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
    <xsl:template match="/comp">
        <comp>
            <xsl:for-each select="./fig">
                <xsl:copy-of select="."/>
                <xsl:variable name="major">
                    <xsl:value-of select="substring-after(substring-before(./@xml:id,'-'),'c')"/>
                </xsl:variable>
                <xsl:variable name="minor">
                    <xsl:value-of select="number(substring-after(./@xml:id,'fig-'))"/>
                </xsl:variable>
                <xsl:variable name="resume_offset">
                    <xsl:if test="./@resumeatnum">
                        <xsl:value-of select="number(./@resumeatnum - $minor)"/>
                    </xsl:if>
                    <xsl:if test="not(./@resumeatnum)">
                        <xsl:if test="./preceding-sibling::*[@resumeatnum]">
                            <xsl:value-of select="number(./preceding-sibling::*[@resumeatnum][1]/@resumeatnum) - number(substring-after(./preceding-sibling::*[@resumeatnum][1]/@xml:id,'fig-'))"/>
                        </xsl:if>
                        <xsl:if test="not(./preceding-sibling::*[@resumeatnum])">
                            <xsl:value-of select="number(0)"/>
                        </xsl:if>
                    </xsl:if>
                </xsl:variable>
                <fignum>
                    <xsl:value-of select="$major"/>
                    <xsl:text>.</xsl:text>
                    <xsl:value-of select="$minor+$resume_offset"/>
                </fignum>
            </xsl:for-each>
        </comp>
    </xsl:template>
</xsl:stylesheet>
于 2012-07-26T19:26:57.607 に答える
0

別のアプローチは、最初のイチジク要素を一致させることから始めることです

<xsl:apply-templates select="fig[1]"/>

次に、 fig要素に一致するメインテンプレートがありますが、「インクリメント」値を保持するパラメーターがあります。名前付きテンプレートとしても機能することに注意してください。

<xsl:template match="fig" name="fig">
   <xsl:param name="sequence" select="1"/>

この中で、 fignum要素を出力できます

<fignum>
   <xsl:value-of 
      select="concat(substring-before(substring(@xml:id, 2, string-length(@xml:id) - 1), '-'), '.', $sequence)"/>
</fignum>

次に、次のfig要素を照合し、パラメーターの値をインクリメントします

  <xsl:apply-templates select="following-sibling::fig[1]">
     <xsl:with-param name="sequence" select="$sequence + 1"/>
  </xsl:apply-templates>

シーケンスをリセットするには、関連する属性を持つfig要素に一致するテンプレートがあり、属性値を指定してnamed-templateを呼び出してオーバーライドできます。

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

これが完全なXSLTです

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

   <xsl:template match="comp">
      <comp>
         <xsl:apply-templates select="fig[1]"/>
      </comp>
   </xsl:template>

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

   <xsl:template match="fig" name="fig">
      <xsl:param name="sequence" select="1"/>
      <fig>
         <xsl:apply-templates select="@*"/>
         <fignum>
            <xsl:value-of select="concat(substring-before(substring(@xml:id, 2, string-length(@xml:id) - 1), '-'), '.', $sequence)"/>
         </fignum>
      </fig>
      <xsl:apply-templates select="following-sibling::fig[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>

サンプルXMLに適用すると、次のように出力されます。

<comp>
   <fig xml:id="c1-fig-001">
      <fignum>1.1</fignum>
   </fig>
   <fig xml:id="c1-fig-002">
      <fignum>1.2</fignum>
   </fig>
   <fig xml:id="c1-fig-003">
      <fignum>1.3</fignum>
   </fig>
   <fig xml:id="c1-fig-004" resumeatnum="7">
      <fignum>1.7</fignum>
   </fig>
   <fig xml:id="c1-fig-005">
      <fignum>1.8</fignum>
   </fig>
   <fig xml:id="c1-fig-006">
      <fignum>1.9</fignum>
   </fig>
   <fig xml:id="c1-fig-007" resumeatnum="18">
      <fignum>1.18</fignum>
   </fig>
   <fig xml:id="c1-fig-008">
      <fignum>1.19</fignum>
   </fig>
   <fig xml:id="c1-fig-009">
      <fignum>1.20</fignum>
   </fig>
</comp>
于 2012-07-26T20:30:36.367 に答える