2

節番号のあるテキストがあります。

ここで、テキストを詩番号で区切り、単一の詩に ID として番号を付けたいと思います。

ソースから番号を取得する方法がわからなかったので、連続した番号を付けましたが、可能であれば、ソースから実際の番号を割り当ててもらいたいです。そのため、1 つの節が欠落している場合、XSLT は連続してカウントされず、番号がスキップされます。

しかし、それ以外にも、<l n="1"/>最初に空の要素を取得するという問題があります。

私の XSLT も何らかの形で一致<p>すると思うので、実際の n="1" は n="2" になります。

どうすれば解決できますか?

私の情報源:

<root>
<p>1 This is 2 a <hi rend="bold">beautiful</hi> example 3 poem 4 for showing! 5 my problem</p> 
</root>

で変換:

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

    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="root/p">
        <p>
        <xsl:variable name="words" select="tokenize(text(),'(1|2|3|4|5|6|7|8|9|0)')" as="xs:string*"/>
        <xsl:for-each select="1 to xs:integer(floor(count($words) div 1))">
            <xsl:variable name="vIndex" select="(.)" as="xs:integer"/>
            <l><xsl:attribute name="n"
            select="position()"/>
                <xsl:value-of select="$words[$vIndex]"/>
            </l>
        </xsl:for-each>
        </p>
    </xsl:template>
</xsl:stylesheet>

私が得るものは次のとおりです。

<root>
    <p>
      <l n="1"/>
      <l n="2"> This is </l>
      <l n="3"> a beautiful example </l>
      <l n="4"> poem </l>
      <l n="5"> for showing </l>
      <l n="6"> my problem</l>
   </p>
</root>

必要な出力は次のとおりです。

<root>
    <p>
      <l n="1"> This is </l>
      <l n="2"> a <hi rend="bold">beautiful</hi> example </l>
      <l n="3"> poem </l>
      <l n="4"> for showing! </l>
      <l n="5"> my problem</l>
   </p>
</root>

編集:例に要素を追加しました。

4

2 に答える 2

0

によって返される最初の要素はtokenize、最初の数字の前に表示されるものになります (この場合、空の文字列)。したがって、最初の数字の後に表示されるものだけが必要であると仮定すると、 (関数tokenizeを使用するなどして) の結果から最初の要素を削除する必要があります。remove

これを試して:

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

    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="root/p">
        <p>
        <xsl:variable name="tokens" select="tokenize(text(),'(1|2|3|4|5|6|7|8|9|0)')" as="xs:string*"/>
        <xsl:variable name="words" select="remove($tokens, 1)" as="xs:string*"/>
        <xsl:for-each select="1 to xs:integer(floor(count($words) div 1))">
            <xsl:variable name="vIndex" select="(.)" as="xs:integer"/>
            <l><xsl:attribute name="n"
            select="position()"/>
                <xsl:value-of select="$words[$vIndex]"/>
            </l>
        </xsl:for-each>
        </p>
    </xsl:template>
</xsl:stylesheet>
于 2013-07-30T13:27:04.783 に答える
0

analyze-stringの代わりに使用tokenize:

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

    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="root/p">
        <p>
          <xsl:analyze-string select="." regex="([0-9]+)([^0-9]*)">
            <xsl:matching-substring>
              <l name="{regex-group(1)}">
                <xsl:value-of select="regex-group(2)"/>
              </l>
            </xsl:matching-substring>
        </xsl:analyze-string>
     </p>

    </xsl:template>
</xsl:stylesheet>

p要素に要素の子があると予想される場合は、より複雑なアプローチが必要です。

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

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="node() | @*" mode="#all">
        <xsl:copy>
            <xsl:apply-templates select="@* |node()" mode="#current"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="root/p">
        <p>
          <xsl:variable name="children">
            <xsl:apply-templates select="node()" mode="wrap-number"/>
          </xsl:variable>
          <xsl:for-each-group select="$children/node()" group-starting-with="n">
            <l n="{.}">
              <xsl:apply-templates select="current-group() except ."/>
            </l>
          </xsl:for-each-group>
        </p>
    </xsl:template>

    <xsl:template match="p//text()" mode="wrap-number">
      <xsl:analyze-string select="." regex="[0-9]+">
        <xsl:matching-substring>
          <n><xsl:value-of select="."/></n>
        </xsl:matching-substring>
        <xsl:non-matching-substring>
          <xsl:value-of select="."/>
        </xsl:non-matching-substring>
      </xsl:analyze-string>
    </xsl:template>

</xsl:stylesheet>

ただし、これは行の番号が要素のテキスト ノードの子に含まれていることが保証されている場合にのみ機能します。p要素の子でも許可されている場合 (例: <p><span>1 This </span>2 is an example.</p>)、さらに作業が必要です。

于 2013-07-30T13:42:05.660 に答える