XSLT - 在内容文本之间的数字和文本之间添加新节点

XSLT - add new node between numbers and text between content text

在 xslt 中是否可以在内容文本中的数字和文本之间添加新节点。

例如:

<doc>
  <a>1 Available accessibility features for....</a>
  <b>..between two teams of 11 players each on a..</b>
  <c>The game is played by 120 million players..</c>
</doc>

我需要在上面 xml 之间的数字和文本之间添加 <s> 节点。所以输出 xml 应该是

<doc>
  <a>1<s/> Available accessibility features for....</a>
  <b>..between two teams of<s/> 11<s/> players each on a..</b>
  <c>The game is played by <s/>120<s/> million  players..</c>
</doc>

我努力寻找任何方法来完成这项任务,但找不到任何好的解决方案。在 xslt 中有什么可能的方法吗?

如前所述,这是 analyze-string 的工作。样式表

<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="text()" priority="5">
  <xsl:analyze-string select="." regex="(^|[^0-9]+)([0-9]+)([^0-9]+|$)">
    <xsl:matching-substring>
      <xsl:if test="string-length(regex-group(1)) gt 0">
        <xsl:value-of select="regex-group(1)"/>
        <s/>
      </xsl:if>
      <xsl:value-of select="regex-group(2)"/>
      <xsl:if test="string-length(regex-group(3)) gt 0">
        <s/>
        <xsl:value-of select="regex-group(3)"/>
      </xsl:if>
    </xsl:matching-substring>
    <xsl:non-matching-substring>
      <xsl:value-of select="."/>
    </xsl:non-matching-substring>
  </xsl:analyze-string>
</xsl:template>

</xsl:stylesheet>

变换

<doc>
  <a>1 Available accessibility features for....</a>
  <b>..between two teams of 11 players each on a..</b>
  <c>The game is played by 120 million players..</c>
</doc>

进入

<doc>
  <a>1<s/> Available accessibility features for....</a>
  <b>..between two teams of <s/>11<s/> players each on a..</b>
  <c>The game is played by <s/>120<s/> million players..</c>
</doc>

这是对马丁回答的简化。 analyze-string 的工作方式是将输入字符串拆分为一系列匹配和不匹配的子字符串,并为每个子字符串使用适当的处理程序。在(非)匹配子字符串处理程序中,position() 函数是该子字符串在子字符串块列表中的位置,last() 是匹配和不匹配子字符串的总数。因此,您可以使用更简单的正则表达式来匹配数字,并使用 position() 来处理最终效果:

<xsl:analyze-string select="." regex="[0-9]+">
  <xsl:matching-substring>
    <xsl:if test="position() gt 1">
      <s/>
    </xsl:if>
    <xsl:value-of select="." />
    <xsl:if test="position() lt last()">
      <s/>
    </xsl:if>
  </xsl:matching-substring>
  <xsl:non-matching-substring>
    <xsl:value-of select="." />
  </xsl:non-matching-substring>
</xsl:analyze-string>

如果在该匹配子串之前有一个不匹配的子串,则第一个 if 为真,如果还有至少一个不匹配的子串仍在后面,则第二个 if 为真当前匹配的一个(虽然一般情况下不一定是这种情况,对于这个特定的正则表达式我们可以保证匹配和不匹配的子串将严格交替。不可能得到两个匹配的子串彼此相邻,带有贪婪的 + 量词)。