XSLT 转换带点分隔字符的字符串
XSLT transforming string with dot separated characters
我正在使用 XSLT 转换 XML。
我想用点分割节点 initials
的字符:
我需要为 initials
更改以下内容:
- 每个字符以点分隔
- 将每个字符大写
- 删除空格
如果字符不存在,我找不到拆分字符和插入点的方法。
<?xml version="1.0" encoding="UTF-8"?>
<jsonObject>
<account>
<initials>ABC</initials>
</account>
<account>
<initials>A BC</initials>
</account>
<account>
<initials>A.B.C </initials>
</account>
<account>
<initials>a.B.C</initials>
</account>
</jsonObject>
我想要转换后输出如下:
<results>
<account>
<field name="initials">A.B.C</field>
</account>
<account>
<field name="initials">A.B.C</field>
</account>
<account>
<field name="initials">A.B.C</field>
</account>
<account>
<field name="initials">A.B.C</field>
</account>
</results>
到目前为止我的样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<results>
<xsl:for-each select="account">
<account>
<field name="initials"><xsl:value-of select="upper-case(translate(initials, ' ',''))"/></field>
</account>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
我找到了解决方案:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:functx="http://www.functx.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:function name="functx:chars" as="xs:string*" xmlns:functx="http://www.functx.com">
<xsl:param name="arg" as="xs:string?"/>
<xsl:sequence select="
for $ch in string-to-codepoints($arg)
return codepoints-to-string($ch)
"/>
</xsl:function>
<xsl:template match="/*">
<results>
<xsl:for-each select="account">
<account>
<field name="initials"><xsl:value-of select="string-join(functx:chars(upper-case(translate(translate(initials, '.',''), ' ',''))), '.')"/></field>
</account>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
您可以使用 RegEx 来 fn:replace 每个字符,字符本身后跟一个点:
首先,删除所有其他带有translate
的字符:
translate(.,' .,','')
二、将所有字符转为大写:
upper-case(.)
将每个字符替换为其后跟一个点:
replace(.,'(.)','.'))
删除前导和尾随空格:
normalize-space(.)
删除最后一个点:
replace(.,'\.$','')
这是 XSLT-2.0 代码:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<results>
<xsl:for-each select="account">
<account>
<field name="initials"><xsl:value-of select="replace(normalize-space(replace(upper-case(translate(.,' .,','')),'(.)','.')),'\.$','')"/></field>
</account>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
在 XSLT 3.0 中,您可以使用 analyze-string
函数:
<xsl:template match="initials">
<xsl:copy>
<xsl:value-of
select="analyze-string(., '\p{L}')/*:match => string-join('.') => upper-case()"/>
</xsl:copy>
</xsl:template>
https://xsltfiddle.liberty-development.net/pPJ9hE3
或者您可以在类似于您的方法的函数中使用 XSLT 2/3 xsl:analyze-string
元素:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="2.0">
<xsl:function name="mf:analyze">
<xsl:param name="input" as="xs:string"/>
<xsl:param name="regex" as="xs:string"/>
<xsl:analyze-string select="$input" regex="{$regex}">
<xsl:matching-substring>
<fn:match>
<xsl:value-of select="."/>
</fn:match>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template match="initials">
<xsl:copy>
<xsl:value-of
select="upper-case(
string-join(
mf:analyze(., '\p{L}'),
'.'
)
)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我正在使用 XSLT 转换 XML。
我想用点分割节点 initials
的字符:
我需要为 initials
更改以下内容:
- 每个字符以点分隔
- 将每个字符大写
- 删除空格
如果字符不存在,我找不到拆分字符和插入点的方法。
<?xml version="1.0" encoding="UTF-8"?>
<jsonObject>
<account>
<initials>ABC</initials>
</account>
<account>
<initials>A BC</initials>
</account>
<account>
<initials>A.B.C </initials>
</account>
<account>
<initials>a.B.C</initials>
</account>
</jsonObject>
我想要转换后输出如下:
<results>
<account>
<field name="initials">A.B.C</field>
</account>
<account>
<field name="initials">A.B.C</field>
</account>
<account>
<field name="initials">A.B.C</field>
</account>
<account>
<field name="initials">A.B.C</field>
</account>
</results>
到目前为止我的样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<results>
<xsl:for-each select="account">
<account>
<field name="initials"><xsl:value-of select="upper-case(translate(initials, ' ',''))"/></field>
</account>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
我找到了解决方案:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:functx="http://www.functx.com"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:function name="functx:chars" as="xs:string*" xmlns:functx="http://www.functx.com">
<xsl:param name="arg" as="xs:string?"/>
<xsl:sequence select="
for $ch in string-to-codepoints($arg)
return codepoints-to-string($ch)
"/>
</xsl:function>
<xsl:template match="/*">
<results>
<xsl:for-each select="account">
<account>
<field name="initials"><xsl:value-of select="string-join(functx:chars(upper-case(translate(translate(initials, '.',''), ' ',''))), '.')"/></field>
</account>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
您可以使用 RegEx 来 fn:replace 每个字符,字符本身后跟一个点:
首先,删除所有其他带有
translate
的字符:translate(.,' .,','')
二、将所有字符转为大写:
upper-case(.)
将每个字符替换为其后跟一个点:
replace(.,'(.)','.'))
删除前导和尾随空格:
normalize-space(.)
删除最后一个点:
replace(.,'\.$','')
这是 XSLT-2.0 代码:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<results>
<xsl:for-each select="account">
<account>
<field name="initials"><xsl:value-of select="replace(normalize-space(replace(upper-case(translate(.,' .,','')),'(.)','.')),'\.$','')"/></field>
</account>
</xsl:for-each>
</results>
</xsl:template>
</xsl:stylesheet>
在 XSLT 3.0 中,您可以使用 analyze-string
函数:
<xsl:template match="initials">
<xsl:copy>
<xsl:value-of
select="analyze-string(., '\p{L}')/*:match => string-join('.') => upper-case()"/>
</xsl:copy>
</xsl:template>
https://xsltfiddle.liberty-development.net/pPJ9hE3
或者您可以在类似于您的方法的函数中使用 XSLT 2/3 xsl:analyze-string
元素:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="#all"
version="2.0">
<xsl:function name="mf:analyze">
<xsl:param name="input" as="xs:string"/>
<xsl:param name="regex" as="xs:string"/>
<xsl:analyze-string select="$input" regex="{$regex}">
<xsl:matching-substring>
<fn:match>
<xsl:value-of select="."/>
</fn:match>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template match="initials">
<xsl:copy>
<xsl:value-of
select="upper-case(
string-join(
mf:analyze(., '\p{L}'),
'.'
)
)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>