首页 > 解决方案 > 使用 XSLT 将连字符括在其自己的元素中

问题描述

给定以下 XML:

<p>
  <lb/>Aber, Schertz bey Seite geſetzet; wer mir und ſo viel ehrlichen
  <lb/>Bieder-Maͤnnern nicht glauben will, der probire es bey den haͤuffigen Kirchen-
  <lb/>Sachen, die ein Sangloser Organiſt etwa geſchmadert hat, (denn es gibt frucht-
  <lb/>bare Naͤchte bey dieſen Leuten,  [...]
</p>

有没有一种纯粹的 XSLT 方法可以将它转换成这个?

<p>
  <lb/>Aber, Schertz bey Seite geſetzet; wer mir und ſo viel ehrlichen
  <lb/>Bieder-Maͤnnern nicht glauben will, der probire es bey den haͤuffigen Kirchen<pc force="strong">-</pc>
  <lb/>Sachen, die ein Sangloser Organiſt etwa geſchmadert hat, (denn es gibt frucht<pc force="weak">-</pc>
  <lb/>bare Naͤchte bey dieſen Leuten,  [...]
</p>

如果<lb>元素后面的第一个字母是大写字母,则force属性应为strong,否则为weak

目前,我完全被困在如何选择一个以某个字母 ( -)结尾的文本节点和一个<lb>本身后跟大写字母的 -sibling ...

标签: xmlxslttei

解决方案


xsl:mode使用 XSLT 3(但仅用于使用和使用||而不是声明身份转换,concat()并且analyze-string可以替换为xsl:analyze-string以下示例

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">
  
  <xsl:param name="sep" as="xs:string">-</xsl:param>
  
  <xsl:param name="pattern" as="xs:string" select="'(' || $sep || ')' || '(\s*)$'"/>

  <xsl:mode on-no-match="shallow-copy"/>
  
  <xsl:template match="p/text()[matches(., $pattern)][following-sibling::node()[1][self::lb]]">
    <xsl:value-of select="replace(., $pattern, '')"/>
    <pc force="{if (following-sibling::node()[2][self::text()[matches(., '^\p{Lu}')]]) then 'strong' else 'weak'}">{$sep}</pc>
    <xsl:value-of select="analyze-string(., $pattern)//*:group[@nr = 2]"/>
  </xsl:template>

</xsl:stylesheet>

应该做。如果文本可以后跟 ,则匹配文本节点的模式可能需要更具体<lb/><foo>...</foo>,例如,lb不一定要跟在您的示例中的文本节点之后。


推荐阅读