首页 > 解决方案 > XSLT 2.0 修剪最终 HTML 输出的文本长度

问题描述

XSLT 小提琴在这里:https ://xsltfiddle.liberty-development.net/bFDb2Dh/2

在 XSL 2.0 中,我从 eXist-db Lucene 搜索函数接收到一小组节点,该函数返回原始 XML,但将搜索项包装在<exist:match/>. 因此,我继续搜索tei:seg并得到以下信息(我将输出包装在一个额外的元素中以供以后处理需要):

<doc>
  <url>http://localhost:8081/exist/apps/deheresi/doc/MS609-0454</url>
  <seg xmlns="http://www.tei-c.org/ns/1.0" type="dep_event" subtype="event" xml:id="MS609-0454-2" corresp="#MS609-0453-7">Item. Dixit<lb break="y" n="11"/>quod 
    <persName nymRef="#abbot_of_Saint_Papoul" role="npar">abbas de 
        <placeName nymRef="#Saint-Papoul_Aude">Sancto Papulo</placeName>
    </persName> ceperat 
    <persName nymRef="#heretics_not_named" role="par">duos hereticos</persName> et 
    <persName nymRef="#Arnald_Savauza_SML-AU" ana="#pFreeHer" role="par">Arnaldus de Savauza</persName> volebat manulevare dictos hereticos. Et rogavit 
    ipsum<lb break="y" n="12"/>testim et 
    <persName nymRef="#Arnald_Forner_SML-AU" ana="#pFreeHer" role="par">Arnaldum Fornier</persName> et 
    <persName nymRef="#Raimund_Forner_SML-AU" ana="#pFreeHer" role="par">Raimundum Fornier</persName>, fratres,  
    quod irent cum eo 
    ad abbatem de <placeName type="event_loc" nymRef="#Saint-Papoul_Abbey">Sancto<lb break="y" n="14"/>Papulo</placeName> 
    et manulevarent hereticos. Et dictus 
    <persName nymRef="#Arnald_Savauza_SML-AU" ana="#pFreeHer" role="ref">Arnaldus de Savauza</persName> 
    dixit quod dictus abbas promiserat ei quod redderet sibi dictos<lb break="y" n="15"/>
    hereticos pro mille <exist:match xmlns:exist="http://exist.sourceforge.net/NS/exist">solidis</exist:match> tholosanis. Et 
    <persName nymRef="#Bernard_Alzeu_SML-AU" ana="#pFreeHer" role="ref">Bernardus Alzeus</persName> et 
    <persName nymRef="#Ysarn_de_Gibel_SML-AU" ana="#pFreeHer" role="ref">Ysarnus de Gibel</persName> portabant illos denarios. 
    Sed non potuerunt dictos hereticos ma<lb break="n" n="16"/>nulevare. 
    <date type="event_date" when="1237">Et sunt anni VIIIor vel circa.</date>
  </seg>
</doc>

在 XSLT 中,我通过一些转换将其输出到 HTML 中。但是,输出如下所示:

<td>Item. Dixit quod 
   abbas de 
   Sancto Papulo
   ceperat 
   duos hereticos et 
   Arnaldus de Savauza volebat manulevare dictos hereticos. Et rogavit 
   ipsum testim et 
   Arnaldum Fornier et 
   Raimundum Fornier, fratres,  
   quod irent cum eo 
   ad abbatem de Sancto Papulo 
   et manulevarent hereticos. Et dictus 
   Arnaldus de Savauza 
   dixit quod dictus abbas promiserat ei quod redderet sibi dictos 
   hereticos pro mille <span class="search-hit">
   <a href="http://localhost:8081/exist/apps/deheresi/doc/MS609-0454"> 
   solidis</a></span> tholosanis. Et 
   Bernardus Alzeus et 
   Ysarnus de Gibel portabant illos denarios. 
   Sed non potuerunt dictos hereticos manulevare. 
   Et sunt anni VIIIor vel circa.
</td>

但我希望用省略号缩短最终输出:

<td>...dictus abbas 
  promiserat ei quod redderet sibi dictos 
  hereticos pro mille <span class="search-hit"><a 
  href="http://localhost:8081/exist/apps/deheresi/doc/MS609-0454"> 
  solidis</a></span> tholosanis. Et 
  Bernardus Alzeus et 
  Ysarnus de Gibel portabant illos...
</td>

内容两侧的文本输出<span class="search-hit"/>仅限于x字符数。(进一步,如果可能,申请normalize-space()清理原始文档中的字符间距问题。)

我还没有找到任何想法如何在当前的 XSL 转换中解决这个问题,只有在后处理中。

提前谢谢了。

标签: xsltxslt-2.0

解决方案


您可以将从现有代码中获得的tei:seg相应结果的内容存储在变量中td

<xsl:template match="tei:seg">
    <xsl:variable name="search-hit">
        <xsl:apply-templates/>
    </xsl:variable>
    <td>
        <xsl:apply-templates select="$search-hit" mode="trim"/>
    </td>
</xsl:template>

然后您可以通过另一种模式推送该内容,该模式具有文本节点的模板以进行修剪:

<xsl:param name="trim-to" as="xs:integer" select="60"/>

<xsl:template match="text()[1]" mode="trim">
    <xsl:variable name="normalized" as="xs:string" select="normalize-space(.)"/>
    <xsl:value-of select="concat('...', substring($normalized, string-length($normalized) - $trim-to))"/>
</xsl:template>

<xsl:template match="text()[last()]" mode="trim">
    <xsl:variable name="normalized" as="xs:string" select="normalize-space(.)"/>
    <xsl:value-of select="concat(substring($normalized, 1, $trim-to), '...')"/>
</xsl:template>

<xsl:template match="span[@class = 'search-hit']" mode="trim">
    <xsl:copy-of select="."/>
</xsl:template>

replace可以使用和/或tokenize和/或在文本节点模板中微调执行修剪/规范化的代码,xsl:analyze-string但这只有在修剪所需的算法明确时才有可能。

小提琴在https://xsltfiddle.liberty-development.net/bFDb2Dh/3进行了调整。


推荐阅读