【发布时间】:2018-05-12 14:43:05
【问题描述】:
如何使用xslt从xml节点获取子串的子串?
例如
输入:
<node>This Is W3 School</node>
输出:
<node>TIWS</node>
在这里,我想获取每个子字符串的第一个字母,用空格分隔。
【问题讨论】:
标签: xml xslt xslt-1.0 xslt-2.0
如何使用xslt从xml节点获取子串的子串?
例如
输入:
<node>This Is W3 School</node>
输出:
<node>TIWS</node>
在这里,我想获取每个子字符串的第一个字母,用空格分隔。
【问题讨论】:
标签: xml xslt xslt-1.0 xslt-2.0
您可以轻松地在node 元素的上下文中使用tokenize(., ' ') 来获取字符串序列,然后您可以使用substring 函数获取第一个字母,例如在 XSLT 3 tokenize(., ' ')!substring(., 1, 1) 或 XSLT 2 for $token in tokenize(., ' ') return substring($token, 1, 1) 中。
然后使用xsl:value-of 输出结果,例如在 XSLT 3 中
<xsl:template match="node">
<xsl:copy>
<xsl:value-of select="tokenize(., ' ')!substring(., 1, 1)" separator=""/>
</xsl:copy>
</xsl:template>
https://xsltfiddle.liberty-development.net/6qVRKvY
或在 XSLT 2 中使用
<xsl:template match="node">
<xsl:copy>
<xsl:value-of select="for $token in tokenize(., ' ') return substring($token, 1, 1)" separator=""/>
</xsl:copy>
</xsl:template>
【讨论】:
另一种选择是将fn:replace() 与正则表达式和捕获组一起使用:
fn:replace("This Is W3 School", "([A-Z])\w+\s?", "$1")
【讨论】:
感谢您的所有回答。 当我使用 xslt 版本:1.0 时,我编写了子字符串函数来获得所需的输出。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:template match="node">
<node1>
<xsl:value-of select="substring(substring-before(normalize-space(substring-after(//node,'')),' '),1,1)"/>
<xsl:value-of select="substring(substring-after(normalize-space(substring-after(//node,'')),' '),1,1)"/>
<xsl:value-of select="substring(substring-before(normalize-space(substring-after(normalize-space(substring-after(//node,' ')),' ')),' '),1,1)"/>
<xsl:value-of select="substring(substring-after(normalize-space(substring-after(normalize-space(substring-after(//node,' ')),' ')),' '),1,1)"/>
</node1>
</xsl:template>
</xsl:stylesheet>
如果我可以减少相同 xslt 版本 1.0 中的代码,请告诉我
【讨论】:
node 元素,还可以处理超过 5 个子字符串。
<xsl:template match="node">
<xsl:variable name="s" select="tokenize(.,' ')"/>
<xsl:element name="node">
<xsl:for-each select="$s">
<xsl:value-of select="substring(.,1,1)"/>
</xsl:for-each>
</xsl:element>
</xsl:template>
First of all tokenize the string then use substring for your desire output
【讨论】:
如果您无法使用 XSLT 1.0,您可以使用递归模板调用来处理字符串。
示例...
XML 输入
<doc>
<node>This Is W3 School</node>
<node>One Two Three Four Five Six</node>
<node>Hello </node>
<node> X Y Z </node>
<node/>
</doc>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node">
<xsl:copy>
<xsl:call-template name="first_letters"/>
</xsl:copy>
</xsl:template>
<xsl:template name="first_letters">
<xsl:param name="input" select="normalize-space()"/>
<xsl:variable name="remaining" select="substring-after($input,' ')"/>
<xsl:value-of select="substring($input,1,1)"/>
<xsl:if test="$input">
<xsl:call-template name="first_letters">
<xsl:with-param name="input" select="$remaining"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
XML 输出
<doc>
<node>TIWS</node>
<node>OTTFFS</node>
<node>H</node>
<node>XYZ</node>
<node/>
</doc>
【讨论】: