我有这样的XML代码段:
...
<housenumber>23</housenumber>
...
<housenumber>453a</housenumber>
...
<housenumber>76-79</housenumber>
...
<housenumber>12 foo bar something 43</housenumber>
...
如何使用XSLT将这些住宅数量分成两部分,以便我得到两个变量 - 第一个包含&#34;从第1位到第一次出现非数字字符的所有内容&#34;第二个包含&#34;其他一切&#34;?
这样的事情:
...
<housenumber>23</housenumber>
<!-- v1 = 23, v2 = null -->
...
<housenumber>453a</housenumber>
<!-- v1 = 453, v2 = a -->
...
<housenumber>76-79</housenumber>
<!-- v1 = 76, v2 = -79 -->
...
<housenumber>12 foo bar something 43</housenumber>
<!-- v1 = 12, v2 = foo bar something 43 -->
...
任何提示/想法?
感谢。
答案 0 :(得分:2)
正如评论中已经指出的,analyze-string
可以提供帮助,这是一个使用XSLT 3.0(由Saxon 9.7或Exselt支持)的示例,它使用了XPath 3.0函数analyze-string
({ {3}})
<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:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math fn"
version="3.0">
<xsl:template match="root">
<xsl:variable name="matches" select="housenumber/analyze-string(., '(^[0-9]+)([^0-9]?.*)')//fn:match"/>
<xsl:variable name="v1" select="$matches//fn:group[@nr = 1]/xs:integer(.)"/>
<xsl:variable name="v2" select="$matches//fn:group[@nr = 2]/string()"/>
<integers>
<xsl:value-of select="$v1" separator=","/>
</integers>
<strings>
<xsl:value-of select="$v2" separator=","/>
</strings>
</xsl:template>
</xsl:stylesheet>
使用样本
<root>
<housenumber>23</housenumber>
...
<housenumber>453a</housenumber>
...
<housenumber>76-79</housenumber>
...
<housenumber>12 foo bar something 43</housenumber>
</root>
我得到了输出
<integers>23,453,76,12</integers><strings>,a,-79, foo bar something 43</strings>
使用XSLT 2.0,您可以使用xsl:analyze-string
指令:
<?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:template match="root">
<xsl:variable name="matches" as="element(match)*">
<xsl:apply-templates select="housenumber"/>
</xsl:variable>
<xsl:variable name="v1" select="$matches//group[@nr = 1]/xs:integer(.)"/>
<xsl:variable name="v2" select="$matches//group[@nr = 2]/string()"/>
<integers>
<xsl:value-of select="$v1" separator=","/>
</integers>
<strings>
<xsl:value-of select="$v2" separator=","/>
</strings>
</xsl:template>
<xsl:template match="housenumber">
<xsl:analyze-string select="." regex="(^[0-9]+)([^0-9]?.*)">
<xsl:matching-substring>
<match>
<group nr="1">
<xsl:value-of select="regex-group(1)"/>
</group>
<group nr="2">
<xsl:value-of select="regex-group(2)"/>
</group>
</match>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>