0

我有以下 2 个 xml 案例,我想在其中链接它们,这里我想使用 XSLT 1.0,而不是 2.0 和 RE。在这里,我正在尝试尽可能多地自动化我的脚本,但是我陷入了存在以下任何情况的地方。请让我知道我该如何解决。

情况1:

<para>See Chapter 9. </para>

案例2:

<para>Many parties often come from different localities 
and therefore jurisdiction of arbitration can often be 
an issue for the arbitration commission to determine in 
Chapter 12. Enforcement of an award can also be another 
issue of concern.</para>

案例3:

<para>Distribution rights for products or services 
disputes are common in China. Many brand holders 
authorised other legal entities or individuals to use 
their brand names under certain conditions and 
restrictions see paras.2.213 and 4.214. The other 
legal entities/persons need to abide by the franchise 
agreement. Many disputes occur due to the lapse of the 
franchise agreement, misconduct of the franchisee in the 
execution of the franchise agreement, non-payment of 
franchise fee and infringement of the franchise rights. 
Arbitration has been used to resolve some of these 
disputes. </para>

案例4:

<para>The award must take into account the enforcement 
issue of the award(refer to para.3.12). The protection 
of properties may need to be addressed during arbitration
and parties may request protection of properties through 
the court system.</para>

案例5:

<para>The claimant indicates that on 21 August 1998(as 
mentioned in Chapter 16) the claimant signed a franchise 
agreement with Beijing Y Company for Y Company to use their 
brand name(refer to para 5.12) to open a restaurant in 
Shanghai namely Shanghai X Famous Roast Duck Ltd</para>

xslt 应该在下面的模板中。这里我使用 para 模板只是为了应用模板,但是在我的代码中有一些条件,只是为了减少它们,我采用了这种方式。

    <xsl:template match="para">
<div class="para">
    <xsl:apply-templates/>
</div>
    </xsl:template>

    <xsl:template match="text()">
    <!-- Match should go here-->
    </xsl:template>

预期输出如下。

情况1:

<div class="para">See <a href="CHA_CH_09">Chapter 9</a>. </div>

案例2:

<div class="para">Many parties often come from different localities 
and therefore jurisdiction of arbitration can often be 
an issue for the arbitration commission to determine in 
<a href="CHA_CH_12">Chapter 12</a>. Enforcement of an award can also be another 
issue of concern.</div>

案例3:

<div class="para">Distribution rights for products or services 
disputes are common in China. Many brand holders 
authorised other legal entities or individuals to use 
their brand names under certain conditions and 
restrictions see paras.<a href="CHA_CH_02/02-213">2.213</a> and<a href="CHA_CH_14/14-214">14.214</a>. The other legal 
entities/persons need to abide by the franchise 
agreement. Many disputes occur due to the lapse of the 
franchise agreement, misconduct of the franchisee in the 
execution of the franchise agreement, non-payment of 
franchise fee  and infringement of the franchise rights. 
Arbitration has been used to resolve some of these 
disputes.</div>

案例4:

<div class="para">The award must take into account the enforcement 
issue of the award(refer to para.<a href="CHA_CH_03/03-012">3.012</a>). The protection 
of properties may need to be addressed during arbitration 
and parties may request protection of properties through 
the court system.</div>

案例5:

<div class="para">The claimant indicates that on 21 August 1998(as 
mentioned in <a href"CHA_CH_16">Chapter 16</a>) the claimant signed a franchise
agreement with Beijing Y Company for Y Company to use their 
brand name(refer to para <a href="CHA_CH_05/05-112">5.112</a>) to open a restaurant in 
Shanghai namely Shanghai X Famous Roast Duck Ltd</div>

谢谢。

4

1 回答 1

1

这里涉及三个可能的问题;目前尚不清楚它们中的哪一个给你带来了困难。

首先,任务是识别以某些形式出现的交叉引用。在具有正则表达式的语言中,我相信您只需在输入中查找以下任何匹配项:

Chapter \d+
para\.\d\.\d+ 
paras\.\d\.\d+ and \d\.\d+

第二个应该是para\.\d+\.\d+(与第三个类似的变化)——只有你的数据可以肯定地说。如果您正在寻找像第三个这样的模式,您可能还需要像paras\.\d\.\d+(, \d\.\d+)* and \d\.\d+and之类的模式para\.\d\.\d+ or \d\.\d+

你可以做两件事来解决这个问题。您可以切换到 XSLT 2.0(为什么您卡在 1.0 中?鉴于 1.0 将导致您解决这个问题的困难,最好是一个好的原因)。或者对于这些模式中的每一个,您可以手动编写一个小的递归命名模板来识别模式并返回匹配的字符串,或者将开始和长度索引返回到文本节点的字符串值,或者其他可以让您处理链接的东西. 在 XSLT 1.0 中手动编写这样的模式识别器可以让人放松,如果您能够并且愿意根据底层有限状态机来考虑它,这真的不是那么难。(如果你不着急,它也有帮助。)

例如,要识别第一个模式,您需要一个状态机,它具有初始状态、已看到字符串“”的第二个状态以及Chapter已看到字符串“ Chapter”和一个或多个十进制数字的第三个状态. 在状态 1 中,如果我们看到“Chapter",我们记录我们当前的位置(我们已经匹配了 8 个字符)并移动到状态 2;如果我们看到其他任何内容,我们返回 0,表示输入与模式不匹配。在状态 2 中,如果我们看到小数digit 我们移动到状态 3 并在输入字符串中前进一位,如果我们看到其他任何内容,我们返回 0 表示失败。在状态 3 中,如果我们看到一个十进制数字,我们在输入中前进一位并停留在状态 3 ; 如果我们看到任何其他内容,我们会通过返回一个表示匹配长度的数字来表示成功(我们知道它从哪里开始;它从最初提交给模板的字符串的开头开始)。我的初稿(未测试)看起来像这样的东西:

<xsl:template name="match-chapter-ref">
  <!--* given a string s (in state 1), find out how long a string
      * is matched by the pattern "Chapter \d+" at the beginning
      * of $s.  Return that number.  Return 0 for no-match. *-->
  <xsl:param name="s" select="''"/>
  <xsl:param name="state" select="1"/>
  <xsl:param name="length-so-far" select="0"/>

  <xsl:choose>
    <!--* State 1:  expecting 'Chapter ' *-->
    <xsl:when test="$state = 1 and starts-with($s,'Chapter ')">
      <xsl:call-template name="match-chapter-ref">
        <xsl:with-param name="s" select="substring($s,9)"/>
        <xsl:with-param name="state" select="2"/>
        <xsl:with-param name="length-so-far" select="8"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:when test="$state = 1 and not(starts-with($s,'Chapter '))">
      <!--* no sale, return 0 as value *-->
      <xsl:value-of select="0"/>
    </xsl:when>

    <!--* State 2:  expecting a decimal digit *-->
    <xsl:when test="$state = 2">
      <xsl:variable name="c" select="substring($s,1,1)"/>
      <xsl:variable name="litmus" select="translate($c,'01234567689','')"/>
      <xsl:choose>
        <xsl:when test="$litmus = ''">
          <!--* $c is a decimal digit *-->
          <xsl:call-template name="match-chapter-ref">
            <xsl:with-param name="s" select="substring($s,2)"/>
            <xsl:with-param name="state" select="3"/>
            <xsl:with-param name="length-so-far" select="$length-so-far + 1"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <!--* no match, return 0 as value *-->
          <xsl:value-of select="0"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>

    <!--* State 3:  consuming further decimal digits *-->
    <xsl:when test="$state = 3">
      <xsl:variable name="c" select="substring($s,1,1)"/>
      <xsl:variable name="litmus" select="translate($c,'01234567689','')"/>
      <xsl:choose>
        <xsl:when test="$litmus = ''">
          <!--* $c is a decimal digit *-->
          <xsl:call-template name="match-chapter-ref">
            <xsl:with-param name="s" select="substring($s,2)"/>
            <xsl:with-param name="state" select="3"/>
            <xsl:with-param name="length-so-far" select="$length-so-far + 1"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <!--* we have a match, return its length *-->
          <xsl:value-of select="$length-so-far"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:when>

    <xsl:otherwise>
      <xsl:message terminate="yes">Unexpected state in template 
        match-chapter-ref, bailing ...</xsl:message>
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>

您将需要类似的模板来测试其他模式的匹配,并且您将需要一些相当复杂的代码来通过寻找最左边的可能匹配来处理文本节点(即最早出现的“ Chapter”或“ paras”或“ para”)。在伪代码中,该模板的逻辑将是:

  • 在 'Chapter'、'para.' 和 'paras.' 上找到第一个匹配项。
  • 找出哪个是最左边的。
  • 在最左边的匹配项之前去掉不匹配的文本并将其写出来。
  • 使用以匹配开头的字符串调用适当的命名模板。
  • 如果命名模板返回的匹配长度为零,则去掉误导性的匹配字符串,将其写入输出,然后递归调用当前模板,字符串的其余部分在左侧。
  • 如果命名模板返回大于零的匹配长度,则剥离链接的文本(“Chapter 12”、“para.3.245”等)并将其传递给命名模板以生成超链接。然后使用输入字符串的其余部分递归到当前模板。

您的第二个问题是生成超链接。从您的示例看来,这可能是对散文链接的数字部分的机械操作;如果不是,您将需要一个查找表。

您的第三个问题是链接文本的规范化。您的示例表明,某些链接在您的数据中保持不变,而有些则发生了变化。例如,第 9 章的链接仍然是第 9 章的链接,第 2.213 段的链接仍然是第 2.213 段的链接。但是第 3.12 和 5.12 段的链接分别成为第 3.012 和 5.112 段的链接。对我来说,这看起来不像是一个算法过程。如果这确实是您的问题的一部分,而不是准备样本数据时的错字,那么祝您好运(并考虑查找表)。

并且......再想想为什么要在 XSLT 1.0 中使用它,它需要大量繁琐的低级字符串操作,而不是在 2.0 中,它会更直接?

于 2013-09-03T15:53:01.567 回答