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

时间:2015-07-09 08:27:37

标签: xml xslt xslt-2.0

在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中这样做吗?

2 个答案:

答案 0 :(得分:3)

正如已经建议的那样,这是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>

答案 1 :(得分:1)

这是马丁答案的简化。 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为真匹配一个(虽然它不一定是一般的情况,对于这个特定的正则表达式我们可以保证匹配和不匹配的子串将严格交替。它不可能得到两个匹配的子串彼此相邻,带有贪婪的+量词。)