str.replace.function.xsl 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. <?xml version="1.0"?>
  2. <xsl:stylesheet version="1.0"
  3. xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  4. xmlns:str="http://exslt.org/strings"
  5. xmlns:func="http://exslt.org/functions"
  6. xmlns:exsl="http://exslt.org/common"
  7. extension-element-prefixes="str exsl func">
  8. <func:function name="str:replace">
  9. <xsl:param name="string" select="''" />
  10. <xsl:param name="search" select="/.." />
  11. <xsl:param name="replace" select="/.." />
  12. <xsl:choose>
  13. <xsl:when test="not($string)">
  14. <func:result select="/.." />
  15. </xsl:when>
  16. <xsl:when test="function-available('exsl:node-set')">
  17. <!-- this converts the search and replace arguments to node sets
  18. if they are one of the other XPath types -->
  19. <xsl:variable name="search-nodes-rtf">
  20. <xsl:copy-of select="$search" />
  21. </xsl:variable>
  22. <xsl:variable name="replace-nodes-rtf">
  23. <xsl:copy-of select="$replace" />
  24. </xsl:variable>
  25. <xsl:variable name="replacements-rtf">
  26. <xsl:for-each select="exsl:node-set($search-nodes-rtf)/node()">
  27. <xsl:variable name="pos" select="position()" />
  28. <replace search="{.}">
  29. <xsl:copy-of select="exsl:node-set($replace-nodes-rtf)/node()[$pos]" />
  30. </replace>
  31. </xsl:for-each>
  32. </xsl:variable>
  33. <xsl:variable name="sorted-replacements-rtf">
  34. <xsl:for-each select="exsl:node-set($replacements-rtf)/replace">
  35. <xsl:sort select="string-length(@search)" data-type="number" order="descending" />
  36. <xsl:copy-of select="." />
  37. </xsl:for-each>
  38. </xsl:variable>
  39. <xsl:variable name="result">
  40. <xsl:choose>
  41. <xsl:when test="not($search)">
  42. <xsl:value-of select="$string" />
  43. </xsl:when>
  44. <xsl:otherwise>
  45. <xsl:call-template name="str:_replace">
  46. <xsl:with-param name="string" select="$string" />
  47. <xsl:with-param name="replacements" select="exsl:node-set($sorted-replacements-rtf)/replace" />
  48. </xsl:call-template>
  49. </xsl:otherwise>
  50. </xsl:choose>
  51. </xsl:variable>
  52. <func:result select="exsl:node-set($result)/node()" />
  53. </xsl:when>
  54. <xsl:otherwise>
  55. <xsl:message terminate="yes">
  56. ERROR: function implementation of str:replace() relies on exsl:node-set().
  57. </xsl:message>
  58. </xsl:otherwise>
  59. </xsl:choose>
  60. </func:function>
  61. <xsl:template name="str:_replace">
  62. <xsl:param name="string" select="''" />
  63. <xsl:param name="replacements" select="/.." />
  64. <xsl:choose>
  65. <xsl:when test="not($string)" />
  66. <xsl:when test="not($replacements)">
  67. <xsl:value-of select="$string" />
  68. </xsl:when>
  69. <xsl:otherwise>
  70. <xsl:variable name="replacement" select="$replacements[1]" />
  71. <xsl:variable name="search" select="$replacement/@search" />
  72. <xsl:choose>
  73. <xsl:when test="not(string($search))">
  74. <xsl:value-of select="substring($string, 1, 1)" />
  75. <xsl:copy-of select="$replacement/node()" />
  76. <xsl:call-template name="str:_replace">
  77. <xsl:with-param name="string" select="substring($string, 2)" />
  78. <xsl:with-param name="replacements" select="$replacements" />
  79. </xsl:call-template>
  80. </xsl:when>
  81. <xsl:when test="contains($string, $search)">
  82. <xsl:call-template name="str:_replace">
  83. <xsl:with-param name="string" select="substring-before($string, $search)" />
  84. <xsl:with-param name="replacements" select="$replacements[position() > 1]" />
  85. </xsl:call-template>
  86. <xsl:copy-of select="$replacement/node()" />
  87. <xsl:call-template name="str:_replace">
  88. <xsl:with-param name="string" select="substring-after($string, $search)" />
  89. <xsl:with-param name="replacements" select="$replacements" />
  90. </xsl:call-template>
  91. </xsl:when>
  92. <xsl:otherwise>
  93. <xsl:call-template name="str:_replace">
  94. <xsl:with-param name="string" select="$string" />
  95. <xsl:with-param name="replacements" select="$replacements[position() > 1]" />
  96. </xsl:call-template>
  97. </xsl:otherwise>
  98. </xsl:choose>
  99. </xsl:otherwise>
  100. </xsl:choose>
  101. </xsl:template>
  102. </xsl:stylesheet>