Xml XSLT-字符串拆分
我的目标是分析给定XML文档的text()节点,并识别大写单词,如果该单词长度大于3,则在3,4个字符(6,7和9,10…)之间添加Xml XSLT-字符串拆分,xml,xslt,xslt-2.0,Xml,Xslt,Xslt 2.0,我的目标是分析给定XML文档的text()节点,并识别大写单词,如果该单词长度大于3,则在3,4个字符(6,7和9,10…)之间添加“*”字符 例如 输入XML: <chap> <para>The BEGINNING of this COLUMN shows the INPUT and output</para> </chap> 此列的开头显示输入和输出 期望输出: <chap> <para>The B
“*”
字符
例如
输入XML:
<chap>
<para>The BEGINNING of this COLUMN shows the INPUT and output</para>
</chap>
此列的开头显示输入和输出
期望输出:
<chap>
<para>The BEG*INN*ING of this COL*UMN shows the INP*UT and output</para>
</chap>
此列的BEG*INN*ING显示输入和输出
我编写了以下xsl来完成此任务
<xsl:template match="para">
<xsl:analyze-string select="." regex="[(A-Z)]">
<xsl:matching-substring>
<xsl:variable name="reg" select="string(regex-group(0))"/>
<xsl:call-template name="add-star">
<xsl:with-param name="str" select="$reg"/>
</xsl:call-template>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
<xsl:template name="add-star">
<xsl:param name="str" as="xs:string"/>
<xsl:if test="string-length($str)>3">
<xsl:call-template name="add-star">
<xsl:with-param name="str" select="substring($str,4,200)"/>
</xsl:call-template>
</xsl:if>
<xsl:sequence select="string-join(substring($str,1,3),'*')"/>
</xsl:template>
但它并没有像预期的那样工作。由于XSLT中没有像oop语言这样的变量,我很难完成这项任务,有人能建议我如何修改代码来完成这项任务吗?怎么样:
<xsl:template match="para">
<xsl:copy>
<xsl:analyze-string select="." regex="([A-Z]+)(\s|$)">
<xsl:matching-substring>
<xsl:variable name="sub" as="xs:string*">
<xsl:for-each select="0 to (string-length(regex-group(1)) - 1) idiv 3">
<xsl:sequence select="substring(regex-group(1), (. ) * 3 + 1, 3)" />
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="string-join($sub, '*')"/>
<xsl:value-of select="regex-group(2)"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:copy>
</xsl:template>
测试:如何:
<xsl:template match="para">
<xsl:copy>
<xsl:analyze-string select="." regex="([A-Z]+)(\s|$)">
<xsl:matching-substring>
<xsl:variable name="sub" as="xs:string*">
<xsl:for-each select="0 to (string-length(regex-group(1)) - 1) idiv 3">
<xsl:sequence select="substring(regex-group(1), (. ) * 3 + 1, 3)" />
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="string-join($sub, '*')"/>
<xsl:value-of select="regex-group(2)"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:copy>
</xsl:template>
测试:下面是另一个支持exslt的xslt-1.0解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:str="http://exslt.org/strings"
xmlns:func="http://exslt.org/functions"
xmlns:my="http://my.org/xsl"
extension-element-prefixes="fn str func">
<xsl:output method="xml" version="1.0" indent="yes"/>
<func:function name="my:to-upper">
<xsl:param name="str" select="''"/>
<func:result select="translate($str, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
</func:function>
<func:function name="my:is-upper">
<xsl:param name="str" select="''"/>
<func:result select="my:to-upper($str) = $str"/>
</func:function>
<xsl:template match="/">
<xsl:apply-templates select="/node()"/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:copy-of select="./@*"/>
<xsl:apply-templates select="./node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:if test="string-length(normalize-space(.)) > 0">
<xsl:for-each select="str:tokenize(., ' ')">
<xsl:choose>
<xsl:when test="my:is-upper(.)">
<xsl:choose>
<xsl:when test="string-length(.) > 3">
<xsl:for-each select="str:tokenize(., '')">
<xsl:value-of select="."/>
<xsl:if test="0 = position() mod 3 and not(position() = last())">
<xsl:text>*</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="not(position() = last())">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
*
在线这里是另一个支持exslt的xslt-1.0解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:str="http://exslt.org/strings"
xmlns:func="http://exslt.org/functions"
xmlns:my="http://my.org/xsl"
extension-element-prefixes="fn str func">
<xsl:output method="xml" version="1.0" indent="yes"/>
<func:function name="my:to-upper">
<xsl:param name="str" select="''"/>
<func:result select="translate($str, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
</func:function>
<func:function name="my:is-upper">
<xsl:param name="str" select="''"/>
<func:result select="my:to-upper($str) = $str"/>
</func:function>
<xsl:template match="/">
<xsl:apply-templates select="/node()"/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{name()}">
<xsl:copy-of select="./@*"/>
<xsl:apply-templates select="./node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:if test="string-length(normalize-space(.)) > 0">
<xsl:for-each select="str:tokenize(., ' ')">
<xsl:choose>
<xsl:when test="my:is-upper(.)">
<xsl:choose>
<xsl:when test="string-length(.) > 3">
<xsl:for-each select="str:tokenize(., '')">
<xsl:value-of select="."/>
<xsl:if test="0 = position() mod 3 and not(position() = last())">
<xsl:text>*</xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="not(position() = last())">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
*
在线