通过区分内容的类型进行链接

时间:2013-09-03 13:27:16

标签: xslt

我有以下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>

CASE4:

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

case5:

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

case5:

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

感谢。

1 个答案:

答案 0 :(得分:1)

这里涉及三个可能的问题;目前尚不清楚哪一个会给你造成困难。

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

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

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

您可以采取两项措施来解决此问题。你可以切换到XSLT 2.0(为什么你会陷入1.0?鉴于难度1.0会导致你解决这个问题,原因最好是一个好的)。或者对于这些模式中的每一个,您可以手动编写一个小的递归命名模板来识别模式,并将匹配的字符串或开始和长度索引返回到文本节点的字符串值,或者其他可以处理链接的其他模式。在XSLT 1.0中手动编码这样的模式识别器可能是一种放松,如果你能够并且愿意用底层的有限状态机来思考它,那真的不是那么难。 (如果你不赶时间,也会有所帮助。)

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

Chapter

你需要类似的模板来测试其他模式的匹配,你需要一些相当繁琐的代码来处理文本节点,方法是寻找最左边的匹配(即最早出现的“{{ 1}}“或”<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“)。在伪代码中,该模板的逻辑将是:

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

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

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

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