0

我有下面的 XML。当我运行 XSLT 时,输出与预期不同。

<toc><tertiaryie>generally, 75/24—75/24/1</tertiaryie>
<secondaryie>Practice Direction, PD1.1/1—PD1.1/9</secondaryie>
<secondaryie>preliminary act</secondaryie>
<secondaryie>collision actions, 75/20</secondaryie>
<secondaryie>failure to lodge, E75/19/32</secondaryie>
</toc>

当我尝试应用以下 xslt.

<xsl:template match="tertiaryie">
  <xsl:variable name="tertClassType">
    <xsl:value-of select="@level"/>
  </xsl:variable>
  <xsl:variable name="tertClassTypName">
    <xsl:value-of select="concat('tertiaryie-', $tertClassType)"/>
  </xsl:variable>
  <div class="tertiaryie">
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="text()">

  <xsl:analyze-string select="." regex="[^,\s—[A-Z]+]+">

    <xsl:matching-substring>
      <xsl:variable name="range" select="tokenize(.,'—')"/>
      <xsl:variable name="pg" select="tokenize(.,'/')"/>
      <xsl:choose>
        <xsl:when test="not(contains('ABCDEFGHIJKLMNOPQRSTUVWXYZ',substring(.,1,1)))">

          <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:when>

        <xsl:otherwise>
          <xsl:choose>
            <xsl:when test="contains('PD',substring(.,1,2))">

              <a href="{concat('HKWBV1_SEC_',substring-after(substring-before(.,'/'),'PD'),'/PPD',translate(substring-after(.,'PD'),'.','-'))}">
                <xsl:value-of select="."/>
              </a>

            </xsl:when>
            <xsl:otherwise>
              <span class="invalid">
                <xsl:value-of select="."/>  
              </span>
            </xsl:otherwise>
          </xsl:choose>

        </xsl:otherwise>
      </xsl:choose>

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

它给了我以下输出。

<div class="tertiaryie"><a href="er:#HKWBV1_ORD_generally/Pgenerally/">generally</a>, <a href="er:#HKWBV1_ORD_75/P75/24">75/24</a>—&lt;a href="er:#HKWBV1_ORD_75/P75/24/1">75/24/1</a></div>

我想要的输出如下。

<div class="tertiaryie">generally, <a href="er:#HKWBV1_ORD_75/P75/24">75/24</a>—&lt;a href="er:#HKWBV1_ORD_75/P75/24/1">75/24/1</a></div>

请让我知道我怎样才能得到这个。这里所有的文本也都被引用了,因为我只想要数字来获得引用。

你可以在这里找到我的整个 XSLT XSLT和 XML 在这里XML

4

2 回答 2

0

由于您的 XSLT 非常复杂,因此需要一段时间。这主要是因为虽然你使用analyze-string你并没有真正利用它的力量。取而代之的是,您事后会进行大量解析,恕我直言,这非常容易出错且难以维护,尤其是在像 XSLT 这样的健谈语言中。

我建议您更改解决方案,让正则表达式完成大部分工作。

text()用以下 XSLT 摘录替换您的模板

<!-- this template replaces the old match pattern -->
<xsl:template match="text()">

  <!-- build the regular expression -->  
  <xsl:variable name="text_pattern" select="'(.*)'"/>
  <xsl:variable name="delimiter_pattern" select="', '"/>
  <xsl:variable name="range_pattern" select="'(\[?)([A-Z]*)(\d+)([A-Z]*)(/|\.)([A-Z]*\d+[A-Z]*)(/([A-Z]*\d+[A-Z]*))?\]?'"/>

  <xsl:analyze-string select="." regex="{$text_pattern}{$delimiter_pattern}{$range_pattern}(—{$range_pattern})?">

    <!-- extract the business values from the expression -->
    <xsl:matching-substring>
      <xsl:variable name="text_part" select="regex-group(1)"/>
      <xsl:variable name="from_range_openingbracket" select="regex-group(2)"/>
      <xsl:variable name="from_range_1_prefix" select="regex-group(3)"/>
      <xsl:variable name="from_range_1" select="regex-group(4)"/>
      <xsl:variable name="from_range_1_suffix" select="regex-group(5)"/>
      <xsl:variable name="from_range_12_delimiter" select="regex-group(6)"/>
      <xsl:variable name="from_range_2" select="regex-group(7)"/>
      <xsl:variable name="from_range_3" select="regex-group(9)"/>
      <xsl:variable name="to_range_opening_bracket" select="regex-group(11)"/>
      <xsl:variable name="to_range_1_prefix" select="regex-group(12)"/>
      <xsl:variable name="to_range_1" select="regex-group(13)"/>
      <xsl:variable name="to_range_1_suffix" select="regex-group(14)"/>
      <xsl:variable name="to_range_12_delimiter" select="regex-group(15)"/>
      <xsl:variable name="to_range_2" select="regex-group(16)"/>
      <xsl:variable name="to_range_3" select="regex-group(18)"/>

      <xsl:choose>

        <xsl:when test="($from_range_1_prefix = 'PD' or $from_range_1_prefix = '') and $from_range_openingbracket = ''">

          <xsl:value-of select="$text_part"/>

          <xsl:call-template name="format_link">
            <xsl:with-param name="range_1_prefix" select="$from_range_1_prefix"/>
            <xsl:with-param name="range_1" select="$from_range_1"/>
            <xsl:with-param name="range_1_suffix" select="$from_range_1_suffix"/>
            <xsl:with-param name="range_12_delimiter" select="$from_range_12_delimiter"/>
            <xsl:with-param name="range_2" select="$from_range_2"/>
            <xsl:with-param name="range_3" select="$from_range_3"/>
          </xsl:call-template>

          <!-- optionally output the second range -->
          <xsl:if test="$to_range_1 != ''">
            <xsl:text>-</xsl:text>
            <xsl:call-template name="format_link">
              <xsl:with-param name="range_1_prefix" select="$to_range_1_prefix"/>
              <xsl:with-param name="range_1" select="$to_range_1"/>
              <xsl:with-param name="range_1_suffix" select="$to_range_1_suffix"/>
              <xsl:with-param name="range_12_delimiter" select="$to_range_12_delimiter"/>
              <xsl:with-param name="range_2" select="$to_range_2"/>
              <xsl:with-param name="range_3" select="$to_range_3"/>
            </xsl:call-template>
          </xsl:if>

        </xsl:when>

        <xsl:otherwise>

          <!-- inall other cases it has to be marked invalid -->
          <span class="invalid">
            <xsl:value-of select="."/>  
          </span>

        </xsl:otherwise>
      </xsl:choose>          
    </xsl:matching-substring>

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

</xsl:template>

<!-- this template formats one hyperlink -->
<xsl:template name="format_link">
  <xsl:param name="range_1_prefix"/>
  <xsl:param name="range_1"/>
  <xsl:param name="range_1_suffix"/>
  <xsl:param name="range_12_delimiter"/>
  <xsl:param name="range_2"/>
  <xsl:param name="range_3"/>

  <xsl:variable name="suffix">
    <xsl:choose>
      <xsl:when test="$range_3 != ''">
        <xsl:value-of select="concat('/', $range_3)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="''"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>
  <xsl:variable name="range_1_formatted" select="format-number(number($range_1), '00')"/>
  <xsl:variable name="url">
    <xsl:choose>
      <xsl:when test="$range_1_prefix = 'PD'">
        <xsl:value-of select="concat('sec_', $range_1, '_', $range_1_prefix, $range_1, $range_1_suffix, '-', $range_2, $suffix)"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="concat('er:#HKWBV1_ORD_', $range_1_formatted, '/P', $range_1_prefix, $range_1_formatted, $range_1_suffix, $range_12_delimiter, $range_2, $suffix)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <a href="{$url}">
    <xsl:value-of select="concat($range_1_prefix, $range_1, $range_1_suffix, $range_12_delimiter, $range_2, $suffix)"/>
  </a>
</xsl:template>

为了进一步完成您的问题,最好创建一个测试输入文件,其中包含您想要涵盖的每个编码变体的一个代表。

于 2013-10-31T00:57:05.527 回答
0

用这个:

<xsl:analyze-string select="." regex="[\d/]+">

这也意味着您可以进一步消除一些复杂性。

于 2013-10-30T16:34:46.383 回答