如何使用 Xpath 替换功能使用案例替换模式

How to use case replacement pattern with Xpath replace function

我有这个 regexp and substitution patterns demo 并且需要在具有 fn:replace 函数的 xpath 上下文中使用它,但我不知道如何正确编写替换字符串可能吗? 我的天真测试是

replace ("dsfjkljsdfjlsjdfABCDdfsfsdff",
             "(\p{Lu})(\p{Lu}+)",
             "\L")

但它抱怨 FORX0004:replace() 中的替换字符串无效:\ 字符后必须跟 \ 或 $

我想你想要例如

<xsl:function name="mf:lower-case-match">
  <xsl:param name="input" as="xs:string"/>
  <xsl:param name="regex" as="xs:string"/>
  <xsl:analyze-string select="$input" regex="{$regex}">
    <xsl:matching-substring>
      <xsl:value-of select="concat(regex-group(1), lower-case(regex-group(2)))"/>
    </xsl:matching-substring>
    <xsl:non-matching-substring>
      <xsl:value-of select="."/>
    </xsl:non-matching-substring>
  </xsl:analyze-string>
</xsl:function>

mf:lower-case-match("dsfjkljsdfjlsjdfABCDdfsfsdff", "(\p{Lu})(\p{Lu}+)")

或者,使用 as="xs:string" 作为声明的函数类型:

<xsl:function name="mf:lower-case-match" as="xs:string">
  <xsl:param name="input" as="xs:string"/>
  <xsl:param name="regex" as="xs:string"/>
  <xsl:value-of>
      <xsl:analyze-string select="$input" regex="{$regex}">
        <xsl:matching-substring>
          <xsl:value-of select="concat(regex-group(1), lower-case(regex-group(2)))"/>
        </xsl:matching-substring>
        <xsl:non-matching-substring>
          <xsl:value-of select="."/>
        </xsl:non-matching-substring>
      </xsl:analyze-string>          
  </xsl:value-of>
</xsl:function>

您需要为任何用户定义的函数声明命名空间,例如xmlns:mf="http://example.com/mf"xsl:stylesheetxsl:transform 根上。

在 XSLT 3 中,您还可以简单地将 analyze-string 函数的结果推送到一个模式,然后对您想要的组执行任何转换:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="text">
      <xsl:copy>
          <xsl:apply-templates select="analyze-string(., '(\p{Lu})(\p{Lu}+)')" mode="lower-case"/>
      </xsl:copy>
  </xsl:template>
  
  <xsl:template match="*:group[@nr = 2]" mode="lower-case">
      <xsl:value-of select="lower-case(.)"/>
  </xsl:template>
  
</xsl:stylesheet>

我认为 XPath 不支持 \L 正则表达式 属性。 @Martin Honnen 的回答可能是最好的,但这里有一个完整的 XPath 2.0 解决方案:

有:

dsfjkljsdfjlsjdfABCDdfsfsdff

XPath :

replace(replace("dsfjkljsdfjlsjdfABCDdfsfsdff","(\p{Lu})(\p{Lu}+)","______"),"_{3}.+_{3}",lower-case(substring-before(substring-after(replace("dsfjkljsdfjlsjdfABCDdfsfsdff","(\p{Lu})(\p{Lu}+)","______"),"___"),"___")))

描述:

P1 : 我们添加 ___ 以识别小写部分 :

replace("dsfjkljsdfjlsjdfABCDdfsfsdff","(\p{Lu})(\p{Lu}+)","______")

P2 : 我们用 :

生成小写部分
lower-case(substring-before(substring-after(resultofP1,"___"),"___"))

我们用 :

连接前面的两个表达式
replace(resultofP1,"_{3}.+_{3}",resultofP2)

输出:

dsfjkljsdfjlsjdfAbcddfsfsdff