XSL 2.0-从嵌套元素生成不同的URL

时间:2018-10-16 11:48:16

标签: xslt tei

我有tei-xml文件,在其中我标记了中世纪文档中的命名实体,尤其是使用<persName/>的人名。一个简单的例子:

<persName nymref="#Bernard_Faure_Senior">Bernardus Fabri senior</persName>

但是,手稿中经常需要标记“ Raimunda uxor Bernardi Fabri”(即“ Raimunda,Bernard Faure的妻子”)。在这里,我以嵌套方式标记两个名称:

<persName nymref="#Raimunda_Faure">Raimunda uxor 
   <persName nymref="#Bernard_Faure_Senior">Bernardi Fabri 
                       senior</persName></persName>

通常,这不是查询数据的问题。但是,我想通过XSLT 2.0为网页输出以下内容,其中每个名称都转换为指向该人自己的网页的URL(使用@nymRef)。上面的应该输出到这个:

 <a href="www.foo.com/person/Raimunda_Faure">Raimunda 
        uxor</a><a href="www.foo.com/person/Bernard_Faure_Senior">Bernardi 
       Fabri<a>

(即... etiam nec tortor erat Raimunda uxor Bernardi Fabri est leo cursus magna,maximus finibus ...)

此外,有时会发生以下情况(两个名称嵌套在一个名称中):

 <persName nymref="#Raimunda_Faure">Raimunda uxor 
   <persName nymref="#Bernard_Faure_Senior">Bernardi Fabri 
                       senior</persName> matris 
   <persName nymRef="Bernard_Faure_Junior">Bernardi 
                       junior</persName></persName>

(尽管永远不会将<persName>嵌套三层)

我完全不知道如何递归区分和对待//persName[x]//persname[x]//persName[x],以使它们成为单独的URL。

URL是从静态值+ after-substring(//tei:persName/@nymRef,'#')生成的。显然,简单的XSL语句返回基数错误:

concat('www.foo.com/person',after-substring(//tei:persName/@nymRef,'#'))

在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

假设您的XML看起来像这样...

<persName nymref="#Raimunda_Faure">Raimunda uxor 
   <persName nymref="#Bernard_Faure_Senior">Bernardi Fabri senior</persName> matris   
   <persName nymRef="Bernard_Faure_Junior">Bernardi junior</persName>
</persName>

然后,您可以通过将该模板添加到XSLT中来实现目标

<xsl:template match="persName">
  <a href="www.foo.com/person/{substring-after(@nymref, '#')}">
    <xsl:value-of select="text()[1]" />
  </a>
  <xsl:apply-templates select="node()[position() > 1]" />
</xsl:template>

(尽管如果要处理TEI,则需要考虑名称空间)。

这不会假设名称中没有其他类型的标签。

编辑:如果名称中还有其他标签,请尝试使用此模板,该模板将包装persName标签中第一个a之前的所有内容

<xsl:template match="persName">
  <xsl:variable name="nested" select="persName[1]|persName[1]/following-sibling::node()" />
  <a href="www.foo.com/person/{substring(@nymref, 2)}">
    <xsl:apply-templates select="node() except $nested" />
  </a>
  <xsl:apply-templates select="$nested" />
</xsl:template>