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

Xml XSLT-在数字和内容文本之间添加新节点,xml,xslt,xslt-2.0,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> </do

在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>

1…的可用辅助功能。。。。
..在两支各有11名队员的队伍之间。。
这个游戏有1.2亿玩家玩。。
我需要在上述xml之间的数字和文本之间添加
节点。因此,输出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>

1…的可用辅助功能。。。。
..在两支各有11名队员的队伍之间。。
这个游戏有1.2亿玩家玩。。

我努力寻找任何方法来完成这项任务,但找不到任何好的解决办法。在xslt中有没有可能做到这一点的方法

如前所述,这是
分析字符串的工作。样式表

<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>

1…的可用辅助功能。。。。
..在两支各有11名队员的队伍之间。。
这个游戏有1.2亿玩家玩。。
进入


1…的可用辅助功能。。。。
..在两支各有11名队员的队伍之间。。
这个游戏有1.2亿玩家玩。。

如前所述,这是分析字符串的工作。样式表

<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>

1…的可用辅助功能。。。。
..在两支各有11名队员的队伍之间。。
这个游戏有1.2亿玩家玩。。
进入


1…的可用辅助功能。。。。
..在两支各有11名队员的队伍之间。。
这个游戏有1.2亿玩家玩。。

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

这是Martin答案的简化。
分析字符串的工作方式是将输入字符串分成一系列匹配和不匹配的子字符串,并对每个子字符串使用适当的处理程序。
位置()
函数是此子字符串在子字符串块列表中的位置,
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
为真(虽然一般情况下不一定如此,但对于这个特定的正则表达式,我们可以保证匹配和不匹配的子字符串将严格交替。不可能用贪婪的
+
量词使两个匹配的子字符串相邻)。

如何定义“数字”这里?这显然不仅仅是数字序列,因为你包括了“百万”这个词,但你没有标记“二”。如果您可以编写一个正则表达式来描述要匹配的内容,那么使用
分析字符串
应该很容易,但是如果这是一项更复杂的自然语言任务,那么另一个工具可能比XSLT更合适。@IanRoberts,我的错。新节点应该只在数字和文本之间添加。我已经更正了这个问题。谢谢为什么将11名玩家的
转换为11名玩家的
(数字前有空格),而将
乘以1.2亿的
转换为
乘以1.2亿的
(数字前没有空格)?如何定义“数字”这里?这显然不仅仅是数字序列,因为你包括了“百万”这个词,但你没有标记“二”。如果您可以编写一个正则表达式来描述要匹配的内容,那么使用
分析字符串
应该很容易,但是如果这是一项更复杂的自然语言任务,那么另一个工具可能比XSLT更合适。@IanRoberts,我的错。新节点应该只在数字和文本之间添加。我已经更正了这个问题。谢谢为什么将11名玩家的
转换为11名玩家的
(数字前有空格),而将1.2亿名玩家的
转换为1.2亿名玩家的
(数字前没有空格)?谢谢你的评论。这解释了我需要知道的一切谢谢你的评论。这解释了我需要知道的一切。:)