如何使用 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:stylesheet
或 xsl: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
我有这个 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:stylesheet
或 xsl: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