多格式字符串转换

时间:2013-10-25 15:20:33

标签: xml regex xslt xslt-2.0

我有以下2个XML案例。

<pg>1/2/1, 1/4/2, 1/4/7, 1/4/8, 1/9/1, 1A/0/11, 3/0/2, 10/1/6, 12/0/2, 12/3/1, 15/2/1, 17/5/2, 19/0/2A, 25/1/1, 28/0/2, 41/1/5, 55/0/2, 55/1/1, 62/3/3, 65/0/2, 65/2/1, 65/4/1, 65/5/4, 69/4/1, 70/0/3, 72/2/11, 72/2/19, 72/6/5, 75/0/2, 75/1/18, 76/0/2, 77/0/3, 78/0/2, 81/1/12, 92/0/2, 100/3/1, 103/0/52, 103/0/53, 121/0/2A, PD1.1/1, PD5.1/2, PD5.4/1, PD18.1/49, B/74, B/75, B/76, P1/1, P1/2, P3/0/2, P3/0/3, P–FM–D4, D4/65, E1/28/1, F1/30/5, F1/35/2, F1/35/5, H1/3, H9/2, J1/60, M2/18, Q1/25/2, R1/10/1, U1/0/4, U1/0/22, U1/112/2, V1/0/2, V2/0/1, V2/1/0 </pg>

<pg>4/9/2, 5/4, 6/2/9, 6/L/27, 13/9/3, 13/9/14, 14/0/2, 14/0/4, 14/1/1—14/1/5, 14/1/7—14/1/10, 14/2/1—14/2/3, 14/2/5, 14/2/7, 14/4/1, 14/4/3, 14/4/4, 14/4/8—14/4/10, 14/4/12, 14/4/14, 14/4/18, 14/4/19, 14/4/21, 14/4/22, 14/4/25, 14/4/26, 14/4/29, 14/4/30, 14/4/33, 14/4/34, 14/4/36, 14/4/37, 14/4/41, 14/4/42, 14/5/1, 14/6/1, 14/7/1—14/7/6, 14/7/8, 14/7/9, 14/7/15, 14/7/18, 14/8/1, 14/8/2, 14/9/1, 14/10/1, 14/11/1, 14A/0/2, 14A/0/3, 14A/2/7, 15/2/3, 15/3/6, 15/4/11, 16/4/9, 16/7/3, 16/8/8, 16/8/10, 16/11/1, 18/1/3, 18/2/5, 19/2/2, 19/2/9, 20/0/2, 20/4/3, 20/8/23, 22/8, 23/3/3, 24/7/1, 25/1, 27/3/6, 28/4/1, 29/10, 29/10/3, 29/11/1, 29/12/4, 32/6/4, 32/6/14, 32/13/8, 33/0/3, 33/4/1, 42/1/4, 42/2/4, 43/1/5, 45/4/2, 47/1/1, 47/1/2, 58/1/4, 59/0/9, 59/0/47, 59/0/55, 59/4, 59/10/35, 62/4/2, 62/App/21, 62/App/27, 71/2/1, 76/6/1, 81/4/2, 81/5/7, 86/0/2, 86/0/3, 86/1/1, 86/1/2, 86/1/3, 86/2/2, 86/4/1, 88/0/2, 88/1/2, 100/3/13, 103/0/26, 103/0/28, 113/0/2, PD8.2/1, PD8.2/2, PD14.1/1, PD16.2/5, E3/0/4</pg>

以下是XSLT(REGEX)。

            <xsl:analyze-string select="." regex="([0-9]+)/([0-9]+)/([0-9]+)|
            ([0-9]+)([A-Z])/([0-9]+)/([0-9]+)|
            ([0-9]+)/([0-9]+)([A-Z])/([0-9]+)|
            ([A-Z])([0-9]+)/([0-9]+)/([0-9]+)|
            ([0-9]+)/([0-9]+)/([0-9]+)([A-Z])">
                <xsl:matching-substring>
                    <a href="{concat('er:#HKWBV1_ORD_',format-number(number(regex-group(1)),'00'),'/P',format-number(number(regex-group(1)),'0'),'/',regex-group(2),'/',regex-group(3))}">

                        <xsl:value-of select="."/>
                    </a>

                </xsl:matching-substring>


            <xsl:non-matching-substring>

                <xsl:analyze-string select="." regex="([0-9]+)/([0-9]+)">
                    <xsl:matching-substring>
                        <a href="{concat('er:#HKWBV1_ORD_',format-number(number(regex-group(1)),'00'),'/P',format-number(number(regex-group(1)),'0'),'/',regex-group(2))}">

                            <xsl:value-of select="."/>
                        </a>
                    </xsl:matching-substring>

                <xsl:non-matching-substring>
                    <xsl:value-of select="."/>
                </xsl:non-matching-substring>
              </xsl:analyze-string>
            </xsl:non-matching-substring>
</xsl:analyze-string>

我正在尝试转换为以下部分

er:#HKWBV1_ORD_01/P1/2/1

这里

er:#HKWBV1_ORD_(content before first slash)/P1(even here number before first slash)/2(content before second slash)/1(content after 2nd slash).

但是我得到了以下结果。

<td class="pgs"><a href="er:#HKWBV1_ORD_01/P1/0/2">1/0/2</a>,<a href="er:#HKWBV1_ORD_01/P1/2/1">1/2/1</a>, <a href="er:#HKWBV1_ORD_01/P1/4/2">1/4/2</a>, <a href="er:#HKWBV1_ORD_01/P1/4/7">1/4/7</a>, <a href="er:#HKWBV1_ORD_01/P1/4/8">1/4/8</a>, <a href="er:#HKWBV1_ORD_01/P1/9/1">1/9/1</a>, 1A/<a href="er:#HKWBV1_ORD_00/P0/11">0/11</a>, <a href="er:#HKWBV1_ORD_03/P3/0/2">3/0/2</a>, <a href="er:#HKWBV1_ORD_10/P10/1/6">10/1/6</a>, <a href="er:#HKWBV1_ORD_12/P12/0/2">12/0/2</a>, <a href="er:#HKWBV1_ORD_12/P12/3/1">12/3/1</a>, <a href="er:#HKWBV1_ORD_15/P15/2/1">15/2/1</a>, <a href="er:#HKWBV1_ORD_17/P17/5/2">17/5/2</a>, <a href="er:#HKWBV1_ORD_19/P19/0/2">19/0/2</a>A, <a href="er:#HKWBV1_ORD_25/P25/1/1">25/1/1</a>, <a href="er:#HKWBV1_ORD_28/P28/0/2">28/0/2</a>, <a href="er:#HKWBV1_ORD_41/P41/1/5">41/1/5</a>, <a href="er:#HKWBV1_ORD_55/P55/0/2">55/0/2</a>, <a href="er:#HKWBV1_ORD_55/P55/1/1">55/1/1</a>, <a href="er:#HKWBV1_ORD_62/P62/3/3">62/3/3</a>, <a href="er:#HKWBV1_ORD_65/P65/0/2">65/0/2</a>, <a href="er:#HKWBV1_ORD_65/P65/2/1">65/2/1</a>, <a href="er:#HKWBV1_ORD_65/P65/4/1">65/4/1</a>, <a href="er:#HKWBV1_ORD_65/P65/5/4">65/5/4</a>, <a href="er:#HKWBV1_ORD_69/P69/4/1">69/4/1</a>, <a href="er:#HKWBV1_ORD_70/P70/0/3">70/0/3</a>, <a href="er:#HKWBV1_ORD_72/P72/2/11">72/2/11</a>, <a href="er:#HKWBV1_ORD_72/P72/2/19">72/2/19</a>, <a href="er:#HKWBV1_ORD_72/P72/6/5">72/6/5</a>, <a href="er:#HKWBV1_ORD_75/P75/0/2">75/0/2</a>, <a href="er:#HKWBV1_ORD_75/P75/1/18">75/1/18</a>, <a href="er:#HKWBV1_ORD_76/P76/0/2">76/0/2</a>, <a href="er:#HKWBV1_ORD_77/P77/0/3">77/0/3</a>, <a href="er:#HKWBV1_ORD_78/P78/0/2">78/0/2</a>, <a href="er:#HKWBV1_ORD_81/P81/1/12">81/1/12</a>, <a href="er:#HKWBV1_ORD_92/P92/0/2">92/0/2</a>, <a href="er:#HKWBV1_ORD_100/P100/3/1">100/3/1</a>, <a href="er:#HKWBV1_ORD_103/P103/0/52">103/0/52</a>, <a href="er:#HKWBV1_ORD_103/P103/0/53">103/0/53</a>, <a href="er:#HKWBV1_ORD_121/P121/0/2">121/0/2</a>A, PD1.<a href="er:#HKWBV1_ORD_01/P1/1">1/1</a>, PD5.<a href="er:#HKWBV1_ORD_01/P1/2">1/2</a>, PD5.<a href="er:#HKWBV1_ORD_04/P4/1">4/1</a>, PD18.<a href="er:#HKWBV1_ORD_01/P1/49">1/49</a>, B/74, B/75, B/76, P<a href="er:#HKWBV1_ORD_01/P1/1">1/1</a>, P<a href="er:#HKWBV1_ORD_01/P1/2">1/2</a>, P<a href="er:#HKWBV1_ORD_03/P3/0/2">3/0/2</a>, P<a href="er:#HKWBV1_ORD_03/P3/0/3">3/0/3</a>, P–FM–D4, D<a href="er:#HKWBV1_ORD_04/P4/65">4/65</a>, E<a href="er:#HKWBV1_ORD_01/P1/28/1">1/28/1</a>, F<a href="er:#HKWBV1_ORD_01/P1/30/5">1/30/5</a>, F<a href="er:#HKWBV1_ORD_01/P1/35/2">1/35/2</a>, F<a href="er:#HKWBV1_ORD_01/P1/35/5">1/35/5</a>, H<a href="er:#HKWBV1_ORD_01/P1/3">1/3</a>, H<a href="er:#HKWBV1_ORD_09/P9/2">9/2</a>, J<a href="er:#HKWBV1_ORD_01/P1/60">1/60</a>, M<a href="er:#HKWBV1_ORD_02/P2/18">2/18</a>, Q<a href="er:#HKWBV1_ORD_01/P1/25/2">1/25/2</a>, R<a href="er:#HKWBV1_ORD_01/P1/10/1">1/10/1</a>, U<a href="er:#HKWBV1_ORD_01/P1/0/4">1/0/4</a>, U<a href="er:#HKWBV1_ORD_01/P1/0/22">1/0/22</a>, U<a href="er:#HKWBV1_ORD_01/P1/112/2">1/112/2</a>, V<a href="er:#HKWBV1_ORD_01/P1/0/2">1/0/2</a>, V<a href="er:#HKWBV1_ORD_02/P2/0/1">2/0/1</a>, V<a href="er:#HKWBV1_ORD_02/P2/1/0">2/1/0</a> </td>

请让我知道如何以上述格式获取输出。我已经得到了一个工作正常的回复但是,当我遇到M-Dash(长连字符)时,连字符前后的字符串将作为单个链接加入。

如果有任何数字,如

 D4/65, E1/28/1, F1/30/5, F1/35/2, F1/35/5, H1/3, H9/2, J1/60, M2/18, Q1/25/2, R1/10/1, U1/0/4, U1/0/22, U1/112/2, V1/0/2, V2/0/1, V2/1/0

应转换为

<span class="invalid">D4/65</span>, <span class="invalid">E1/28/1</span> 

这里的诀窍是如果数字跟随字符,它应该给出上面的输出和

如果输入具有以下

PD2.2/4, PD5.6/8/9

它应该将其转换为

er:#HKWBV1_SEC_2.2/P2.2/4 and er:#HKWBV1_SEC_5.6/P5.6/8/9

由于

1 个答案:

答案 0 :(得分:1)

在我看来,在正则表达式中匹配任何不是空格或逗号的内容会更容易。然后使用xsl:analyze-string

而不是额外的tokenize

示例...

XML输入

<test>
    <pg>1/2/1, 1/4/2, 1/4/7, 1/4/8, 1/9/1, 1A/0/11, 3/0/2, 10/1/6, 12/0/2, 12/3/1, 15/2/1, 17/5/2, 19/0/2A, 25/1/1, 28/0/2, 41/1/5, 55/0/2, 55/1/1, 62/3/3, 65/0/2, 65/2/1, 65/4/1, 65/5/4, 69/4/1, 70/0/3, 72/2/11, 72/2/19, 72/6/5, 75/0/2, 75/1/18, 76/0/2, 77/0/3, 78/0/2, 81/1/12, 92/0/2, 100/3/1, 103/0/52, 103/0/53, 121/0/2A, PD1.1/1, PD5.1/2, PD5.4/1, PD18.1/49, B/74, B/75, B/76, P1/1, P1/2, P3/0/2, P3/0/3, P–FM–D4, D4/65, E1/28/1, F1/30/5, F1/35/2, F1/35/5, H1/3, H9/2, J1/60, M2/18, Q1/25/2, R1/10/1, U1/0/4, U1/0/22, U1/112/2, V1/0/2, V2/0/1, V2/1/0 </pg>
    <pg>4/9/2, 5/4, 6/2/9, 6/L/27, 13/9/3, 13/9/14, 14/0/2, 14/0/4, 14/1/1—14/1/5, 14/1/7—14/1/10, 14/2/1—14/2/3, 14/2/5, 14/2/7, 14/4/1, 14/4/3, 14/4/4, 14/4/8—14/4/10, 14/4/12, 14/4/14, 14/4/18, 14/4/19, 14/4/21, 14/4/22, 14/4/25, 14/4/26, 14/4/29, 14/4/30, 14/4/33, 14/4/34, 14/4/36, 14/4/37, 14/4/41, 14/4/42, 14/5/1, 14/6/1, 14/7/1—14/7/6, 14/7/8, 14/7/9, 14/7/15, 14/7/18, 14/8/1, 14/8/2, 14/9/1, 14/10/1, 14/11/1, 14A/0/2, 14A/0/3, 14A/2/7, 15/2/3, 15/3/6, 15/4/11, 16/4/9, 16/7/3, 16/8/8, 16/8/10, 16/11/1, 18/1/3, 18/2/5, 19/2/2, 19/2/9, 20/0/2, 20/4/3, 20/8/23, 22/8, 23/3/3, 24/7/1, 25/1, 27/3/6, 28/4/1, 29/10, 29/10/3, 29/11/1, 29/12/4, 32/6/4, 32/6/14, 32/13/8, 33/0/3, 33/4/1, 42/1/4, 42/2/4, 43/1/5, 45/4/2, 47/1/1, 47/1/2, 58/1/4, 59/0/9, 59/0/47, 59/0/55, 59/4, 59/10/35, 62/4/2, 62/App/21, 62/App/27, 71/2/1, 76/6/1, 81/4/2, 81/5/7, 86/0/2, 86/0/3, 86/1/1, 86/1/2, 86/1/3, 86/2/2, 86/4/1, 88/0/2, 88/1/2, 100/3/13, 103/0/26, 103/0/28, 113/0/2, PD8.2/1, PD8.2/2, PD14.1/1, PD16.2/5, E3/0/4</pg>
</test>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="pg">
        <td class="pgs">
            <xsl:analyze-string select="." regex="[^,\s—]+">
                <xsl:matching-substring>
                    <xsl:variable name="pg" select="tokenize(.,'/')"/>
                    <a href="er:#HKWBV1_ORD_{
                        if (string(number($pg[1]))!='NaN') then 
                            format-number(number($pg[1]),'00') 
                        else 
                            $pg[1]}/P{$pg[1]
                        }/{string-join($pg[position()>1],'/')}">
                        <xsl:value-of select="."/>
                    </a>
                </xsl:matching-substring>
                <xsl:non-matching-substring>
                    <xsl:value-of select="."/>
                </xsl:non-matching-substring>
            </xsl:analyze-string>           
        </td>
    </xsl:template>

</xsl:stylesheet>

XML输出

<test>
   <td class="pgs">
      <a href="er:#HKWBV1_ORD_01/P1/2/1">1/2/1</a>, <a href="er:#HKWBV1_ORD_01/P1/4/2">1/4/2</a>, <a href="er:#HKWBV1_ORD_01/P1/4/7">1/4/7</a>, <a href="er:#HKWBV1_ORD_01/P1/4/8">1/4/8</a>, <a href="er:#HKWBV1_ORD_01/P1/9/1">1/9/1</a>, <a href="er:#HKWBV1_ORD_1A/P1A/0/11">1A/0/11</a>, <a href="er:#HKWBV1_ORD_03/P3/0/2">3/0/2</a>, <a href="er:#HKWBV1_ORD_10/P10/1/6">10/1/6</a>, <a href="er:#HKWBV1_ORD_12/P12/0/2">12/0/2</a>, <a href="er:#HKWBV1_ORD_12/P12/3/1">12/3/1</a>, <a href="er:#HKWBV1_ORD_15/P15/2/1">15/2/1</a>, <a href="er:#HKWBV1_ORD_17/P17/5/2">17/5/2</a>, <a href="er:#HKWBV1_ORD_19/P19/0/2A">19/0/2A</a>, <a href="er:#HKWBV1_ORD_25/P25/1/1">25/1/1</a>, <a href="er:#HKWBV1_ORD_28/P28/0/2">28/0/2</a>, <a href="er:#HKWBV1_ORD_41/P41/1/5">41/1/5</a>, <a href="er:#HKWBV1_ORD_55/P55/0/2">55/0/2</a>, <a href="er:#HKWBV1_ORD_55/P55/1/1">55/1/1</a>, <a href="er:#HKWBV1_ORD_62/P62/3/3">62/3/3</a>, <a href="er:#HKWBV1_ORD_65/P65/0/2">65/0/2</a>, <a href="er:#HKWBV1_ORD_65/P65/2/1">65/2/1</a>, <a href="er:#HKWBV1_ORD_65/P65/4/1">65/4/1</a>, <a href="er:#HKWBV1_ORD_65/P65/5/4">65/5/4</a>, <a href="er:#HKWBV1_ORD_69/P69/4/1">69/4/1</a>, <a href="er:#HKWBV1_ORD_70/P70/0/3">70/0/3</a>, <a href="er:#HKWBV1_ORD_72/P72/2/11">72/2/11</a>, <a href="er:#HKWBV1_ORD_72/P72/2/19">72/2/19</a>, <a href="er:#HKWBV1_ORD_72/P72/6/5">72/6/5</a>, <a href="er:#HKWBV1_ORD_75/P75/0/2">75/0/2</a>, <a href="er:#HKWBV1_ORD_75/P75/1/18">75/1/18</a>, <a href="er:#HKWBV1_ORD_76/P76/0/2">76/0/2</a>, <a href="er:#HKWBV1_ORD_77/P77/0/3">77/0/3</a>, <a href="er:#HKWBV1_ORD_78/P78/0/2">78/0/2</a>, <a href="er:#HKWBV1_ORD_81/P81/1/12">81/1/12</a>, <a href="er:#HKWBV1_ORD_92/P92/0/2">92/0/2</a>, <a href="er:#HKWBV1_ORD_100/P100/3/1">100/3/1</a>, <a href="er:#HKWBV1_ORD_103/P103/0/52">103/0/52</a>, <a href="er:#HKWBV1_ORD_103/P103/0/53">103/0/53</a>, <a href="er:#HKWBV1_ORD_121/P121/0/2A">121/0/2A</a>, <a href="er:#HKWBV1_ORD_PD1.1/PPD1.1/1">PD1.1/1</a>, <a href="er:#HKWBV1_ORD_PD5.1/PPD5.1/2">PD5.1/2</a>, <a href="er:#HKWBV1_ORD_PD5.4/PPD5.4/1">PD5.4/1</a>, <a href="er:#HKWBV1_ORD_PD18.1/PPD18.1/49">PD18.1/49</a>, <a href="er:#HKWBV1_ORD_B/PB/74">B/74</a>, <a href="er:#HKWBV1_ORD_B/PB/75">B/75</a>, <a href="er:#HKWBV1_ORD_B/PB/76">B/76</a>, <a href="er:#HKWBV1_ORD_P1/PP1/1">P1/1</a>, <a href="er:#HKWBV1_ORD_P1/PP1/2">P1/2</a>, <a href="er:#HKWBV1_ORD_P3/PP3/0/2">P3/0/2</a>, <a href="er:#HKWBV1_ORD_P3/PP3/0/3">P3/0/3</a>, <a href="er:#HKWBV1_ORD_P–FM–D4/PP–FM–D4/">P–FM–D4</a>, <a href="er:#HKWBV1_ORD_D4/PD4/65">D4/65</a>, <a href="er:#HKWBV1_ORD_E1/PE1/28/1">E1/28/1</a>, <a href="er:#HKWBV1_ORD_F1/PF1/30/5">F1/30/5</a>, <a href="er:#HKWBV1_ORD_F1/PF1/35/2">F1/35/2</a>, <a href="er:#HKWBV1_ORD_F1/PF1/35/5">F1/35/5</a>, <a href="er:#HKWBV1_ORD_H1/PH1/3">H1/3</a>, <a href="er:#HKWBV1_ORD_H9/PH9/2">H9/2</a>, <a href="er:#HKWBV1_ORD_J1/PJ1/60">J1/60</a>, <a href="er:#HKWBV1_ORD_M2/PM2/18">M2/18</a>, <a href="er:#HKWBV1_ORD_Q1/PQ1/25/2">Q1/25/2</a>, <a href="er:#HKWBV1_ORD_R1/PR1/10/1">R1/10/1</a>, <a href="er:#HKWBV1_ORD_U1/PU1/0/4">U1/0/4</a>, <a href="er:#HKWBV1_ORD_U1/PU1/0/22">U1/0/22</a>, <a href="er:#HKWBV1_ORD_U1/PU1/112/2">U1/112/2</a>, <a href="er:#HKWBV1_ORD_V1/PV1/0/2">V1/0/2</a>, <a href="er:#HKWBV1_ORD_V2/PV2/0/1">V2/0/1</a>, <a href="er:#HKWBV1_ORD_V2/PV2/1/0">V2/1/0</a> 
   </td>
   <td class="pgs">
      <a href="er:#HKWBV1_ORD_04/P4/9/2">4/9/2</a>, <a href="er:#HKWBV1_ORD_05/P5/4">5/4</a>, <a href="er:#HKWBV1_ORD_06/P6/2/9">6/2/9</a>, <a href="er:#HKWBV1_ORD_06/P6/L/27">6/L/27</a>, <a href="er:#HKWBV1_ORD_13/P13/9/3">13/9/3</a>, <a href="er:#HKWBV1_ORD_13/P13/9/14">13/9/14</a>, <a href="er:#HKWBV1_ORD_14/P14/0/2">14/0/2</a>, <a href="er:#HKWBV1_ORD_14/P14/0/4">14/0/4</a>, <a href="er:#HKWBV1_ORD_14/P14/1/1">14/1/1</a>—<a href="er:#HKWBV1_ORD_14/P14/1/5">14/1/5</a>, <a href="er:#HKWBV1_ORD_14/P14/1/7">14/1/7</a>—<a href="er:#HKWBV1_ORD_14/P14/1/10">14/1/10</a>, <a href="er:#HKWBV1_ORD_14/P14/2/1">14/2/1</a>—<a href="er:#HKWBV1_ORD_14/P14/2/3">14/2/3</a>, <a href="er:#HKWBV1_ORD_14/P14/2/5">14/2/5</a>, <a href="er:#HKWBV1_ORD_14/P14/2/7">14/2/7</a>, <a href="er:#HKWBV1_ORD_14/P14/4/1">14/4/1</a>, <a href="er:#HKWBV1_ORD_14/P14/4/3">14/4/3</a>, <a href="er:#HKWBV1_ORD_14/P14/4/4">14/4/4</a>, <a href="er:#HKWBV1_ORD_14/P14/4/8">14/4/8</a>—<a href="er:#HKWBV1_ORD_14/P14/4/10">14/4/10</a>, <a href="er:#HKWBV1_ORD_14/P14/4/12">14/4/12</a>, <a href="er:#HKWBV1_ORD_14/P14/4/14">14/4/14</a>, <a href="er:#HKWBV1_ORD_14/P14/4/18">14/4/18</a>, <a href="er:#HKWBV1_ORD_14/P14/4/19">14/4/19</a>, <a href="er:#HKWBV1_ORD_14/P14/4/21">14/4/21</a>, <a href="er:#HKWBV1_ORD_14/P14/4/22">14/4/22</a>, <a href="er:#HKWBV1_ORD_14/P14/4/25">14/4/25</a>, <a href="er:#HKWBV1_ORD_14/P14/4/26">14/4/26</a>, <a href="er:#HKWBV1_ORD_14/P14/4/29">14/4/29</a>, <a href="er:#HKWBV1_ORD_14/P14/4/30">14/4/30</a>, <a href="er:#HKWBV1_ORD_14/P14/4/33">14/4/33</a>, <a href="er:#HKWBV1_ORD_14/P14/4/34">14/4/34</a>, <a href="er:#HKWBV1_ORD_14/P14/4/36">14/4/36</a>, <a href="er:#HKWBV1_ORD_14/P14/4/37">14/4/37</a>, <a href="er:#HKWBV1_ORD_14/P14/4/41">14/4/41</a>, <a href="er:#HKWBV1_ORD_14/P14/4/42">14/4/42</a>, <a href="er:#HKWBV1_ORD_14/P14/5/1">14/5/1</a>, <a href="er:#HKWBV1_ORD_14/P14/6/1">14/6/1</a>, <a href="er:#HKWBV1_ORD_14/P14/7/1">14/7/1</a>—<a href="er:#HKWBV1_ORD_14/P14/7/6">14/7/6</a>, <a href="er:#HKWBV1_ORD_14/P14/7/8">14/7/8</a>, <a href="er:#HKWBV1_ORD_14/P14/7/9">14/7/9</a>, <a href="er:#HKWBV1_ORD_14/P14/7/15">14/7/15</a>, <a href="er:#HKWBV1_ORD_14/P14/7/18">14/7/18</a>, <a href="er:#HKWBV1_ORD_14/P14/8/1">14/8/1</a>, <a href="er:#HKWBV1_ORD_14/P14/8/2">14/8/2</a>, <a href="er:#HKWBV1_ORD_14/P14/9/1">14/9/1</a>, <a href="er:#HKWBV1_ORD_14/P14/10/1">14/10/1</a>, <a href="er:#HKWBV1_ORD_14/P14/11/1">14/11/1</a>, <a href="er:#HKWBV1_ORD_14A/P14A/0/2">14A/0/2</a>, <a href="er:#HKWBV1_ORD_14A/P14A/0/3">14A/0/3</a>, <a href="er:#HKWBV1_ORD_14A/P14A/2/7">14A/2/7</a>, <a href="er:#HKWBV1_ORD_15/P15/2/3">15/2/3</a>, <a href="er:#HKWBV1_ORD_15/P15/3/6">15/3/6</a>, <a href="er:#HKWBV1_ORD_15/P15/4/11">15/4/11</a>, <a href="er:#HKWBV1_ORD_16/P16/4/9">16/4/9</a>, <a href="er:#HKWBV1_ORD_16/P16/7/3">16/7/3</a>, <a href="er:#HKWBV1_ORD_16/P16/8/8">16/8/8</a>, <a href="er:#HKWBV1_ORD_16/P16/8/10">16/8/10</a>, <a href="er:#HKWBV1_ORD_16/P16/11/1">16/11/1</a>, <a href="er:#HKWBV1_ORD_18/P18/1/3">18/1/3</a>, <a href="er:#HKWBV1_ORD_18/P18/2/5">18/2/5</a>, <a href="er:#HKWBV1_ORD_19/P19/2/2">19/2/2</a>, <a href="er:#HKWBV1_ORD_19/P19/2/9">19/2/9</a>, <a href="er:#HKWBV1_ORD_20/P20/0/2">20/0/2</a>, <a href="er:#HKWBV1_ORD_20/P20/4/3">20/4/3</a>, <a href="er:#HKWBV1_ORD_20/P20/8/23">20/8/23</a>, <a href="er:#HKWBV1_ORD_22/P22/8">22/8</a>, <a href="er:#HKWBV1_ORD_23/P23/3/3">23/3/3</a>, <a href="er:#HKWBV1_ORD_24/P24/7/1">24/7/1</a>, <a href="er:#HKWBV1_ORD_25/P25/1">25/1</a>, <a href="er:#HKWBV1_ORD_27/P27/3/6">27/3/6</a>, <a href="er:#HKWBV1_ORD_28/P28/4/1">28/4/1</a>, <a href="er:#HKWBV1_ORD_29/P29/10">29/10</a>, <a href="er:#HKWBV1_ORD_29/P29/10/3">29/10/3</a>, <a href="er:#HKWBV1_ORD_29/P29/11/1">29/11/1</a>, <a href="er:#HKWBV1_ORD_29/P29/12/4">29/12/4</a>, <a href="er:#HKWBV1_ORD_32/P32/6/4">32/6/4</a>, <a href="er:#HKWBV1_ORD_32/P32/6/14">32/6/14</a>, <a href="er:#HKWBV1_ORD_32/P32/13/8">32/13/8</a>, <a href="er:#HKWBV1_ORD_33/P33/0/3">33/0/3</a>, <a href="er:#HKWBV1_ORD_33/P33/4/1">33/4/1</a>, <a href="er:#HKWBV1_ORD_42/P42/1/4">42/1/4</a>, <a href="er:#HKWBV1_ORD_42/P42/2/4">42/2/4</a>, <a href="er:#HKWBV1_ORD_43/P43/1/5">43/1/5</a>, <a href="er:#HKWBV1_ORD_45/P45/4/2">45/4/2</a>, <a href="er:#HKWBV1_ORD_47/P47/1/1">47/1/1</a>, <a href="er:#HKWBV1_ORD_47/P47/1/2">47/1/2</a>, <a href="er:#HKWBV1_ORD_58/P58/1/4">58/1/4</a>, <a href="er:#HKWBV1_ORD_59/P59/0/9">59/0/9</a>, <a href="er:#HKWBV1_ORD_59/P59/0/47">59/0/47</a>, <a href="er:#HKWBV1_ORD_59/P59/0/55">59/0/55</a>, <a href="er:#HKWBV1_ORD_59/P59/4">59/4</a>, <a href="er:#HKWBV1_ORD_59/P59/10/35">59/10/35</a>, <a href="er:#HKWBV1_ORD_62/P62/4/2">62/4/2</a>, <a href="er:#HKWBV1_ORD_62/P62/App/21">62/App/21</a>, <a href="er:#HKWBV1_ORD_62/P62/App/27">62/App/27</a>, <a href="er:#HKWBV1_ORD_71/P71/2/1">71/2/1</a>, <a href="er:#HKWBV1_ORD_76/P76/6/1">76/6/1</a>, <a href="er:#HKWBV1_ORD_81/P81/4/2">81/4/2</a>, <a href="er:#HKWBV1_ORD_81/P81/5/7">81/5/7</a>, <a href="er:#HKWBV1_ORD_86/P86/0/2">86/0/2</a>, <a href="er:#HKWBV1_ORD_86/P86/0/3">86/0/3</a>, <a href="er:#HKWBV1_ORD_86/P86/1/1">86/1/1</a>, <a href="er:#HKWBV1_ORD_86/P86/1/2">86/1/2</a>, <a href="er:#HKWBV1_ORD_86/P86/1/3">86/1/3</a>, <a href="er:#HKWBV1_ORD_86/P86/2/2">86/2/2</a>, <a href="er:#HKWBV1_ORD_86/P86/4/1">86/4/1</a>, <a href="er:#HKWBV1_ORD_88/P88/0/2">88/0/2</a>, <a href="er:#HKWBV1_ORD_88/P88/1/2">88/1/2</a>, <a href="er:#HKWBV1_ORD_100/P100/3/13">100/3/13</a>, <a href="er:#HKWBV1_ORD_103/P103/0/26">103/0/26</a>, <a href="er:#HKWBV1_ORD_103/P103/0/28">103/0/28</a>, <a href="er:#HKWBV1_ORD_113/P113/0/2">113/0/2</a>, <a href="er:#HKWBV1_ORD_PD8.2/PPD8.2/1">PD8.2/1</a>, <a href="er:#HKWBV1_ORD_PD8.2/PPD8.2/2">PD8.2/2</a>, <a href="er:#HKWBV1_ORD_PD14.1/PPD14.1/1">PD14.1/1</a>, <a href="er:#HKWBV1_ORD_PD16.2/PPD16.2/5">PD16.2/5</a>, <a href="er:#HKWBV1_ORD_E3/PE3/0/4">E3/0/4</a>
   </td>
</test>

<强>解释

为了解释正则表达式和标记化,让我们使用一个更小的例子:

<pg>1/2/1, 1/4/2</pg>

regex="[^,\s—]+"中的正则表达式xsl:analyze-string匹配的一个或多个字符不是,\s(空格)或 。字符类开头的^表示“不”。

使用缩短的示例,我们将有这两个匹配项(xsl:matching-substring):

1/2/11/4/2

,将由xsl:non-matching-substring输出。

由于匹配子串由/分隔,我们可以使用tokenize()来获取我们可以使用的值序列。可以通过其位置轻松访问这些值。

例如,1/4/2最终成为序列中的3个项目:

1 =第一项
4 =第二项
2 =第三项

上面我的回答中的一个例子是我对$pg[1]的使用。这是变量pg序列中的第一项。

另一个例子是string-join($pg[position()>1],'/')。这加入了位置大于1的所有项目。使用我们的1/4/2示例,我们会得到4/2,因为4是第二项,而2是第三项。 /来自string-join()中的第二个参数。

使用正则表达式和标记化可以很容易地进行复杂的字符串操作。例如,可以为“mdash”范围中的每个值输出单独的条目。一个例子是:

102/9—102/12(102/9至102/12)

成为:

<a href="er:#HKWBV1_ORD_102/P102/9">102/9</a>, <a href="er:#HKWBV1_ORD_102/P102/10">102/10</a>, <a href="er:#HKWBV1_ORD_102/P102/11">102/11</a>, <a href="er:#HKWBV1_ORD_102/P102/12">102/12</a>

代码实际上不会那么复杂:

<xsl:template match="pg">
    <td class="pgs">
        <xsl:analyze-string select="." regex="[^,\s]+">
            <xsl:matching-substring>
                <xsl:variable name="range" select="tokenize(.,'—')"/>
                <xsl:variable name="pg" select="tokenize(.,'/')"/>
                <xsl:choose>
                    <xsl:when test="contains($pg[3],'—')">
                        <xsl:variable name="range-pg" as="item()*">
                            <xsl:for-each select="$range">
                                <xsl:sequence select="tokenize(.,'/')"/>
                            </xsl:for-each>
                        </xsl:variable>
                        <xsl:for-each select="xs:integer($range-pg[3]) to xs:integer($range-pg[6])">
                            <a href="er:#HKWBV1_ORD_{
                                if (string(number($range-pg[1]))!='NaN') then 
                                format-number(number($range-pg[1]),'00') 
                                else 
                                $range-pg[1]}/P{string-join($range-pg[position()=(1,2)],'/')}/{.}">
                                <xsl:value-of select="concat(string-join($range-pg[position()=(1,2)],'/'),'/',.)"/>
                            </a>
                            <xsl:text>, </xsl:text>
                        </xsl:for-each>
                    </xsl:when>
                    <xsl:otherwise>
                        <a href="er:#HKWBV1_ORD_{
                            if (string(number($pg[1]))!='NaN') then 
                            format-number(number($pg[1]),'00') 
                            else 
                            $pg[1]}/P{$pg[1]
                            }/{string-join($pg[position()>1],'/')}">
                            <xsl:value-of select="."/>
                        </a>                            
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>           
    </td>
</xsl:template>