我想用分隔符(_)拆分XML字符串,并希望使用XSL将每个值存储在变量中。我正在使用xsl1.0
我的xml文件
<file>
<filename>ACT_0815_ERS_V7</filename>
</file>
和XSL
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="filename/text()" name="tokenize">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="'_'"/>
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
<item>
<xsl:value-of select="normalize-space($text)"/>
</item>
</xsl:when>
<xsl:otherwise>
<aa><xsl:value-of select="normalize-space(substring-before($text[0], $separator))"/></aa>
<bb><xsl:value-of select="normalize-space(substring-before($text[1], $separator))"/></bb>
<cc><xsl:value-of select="normalize-space(substring-before($text[2], $separator))"/></cc>
<dd><xsl:value-of select="normalize-space(substring-before($text[3], $separator))"/></dd>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $separator)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
以上xsl的错误xml输出
<?xml version="1.0" encoding="UTF-8"?>
<file>
<filename><aa/><bb>ACT</bb><cc/><dd/><aa/><bb>0815</bb><cc/><dd/><aa/><bb>ERS</bb><cc/><dd/><item>V7</item></filename>
</file>
想要输出如下
<?xml version="1.0" encoding="UTF-8"?>
<file>
<aa>ACT</aa>
<bb>0815</bb>
<cc>ERS</cc>
<dd>V7</dd>
</file>
答案 0 :(得分:1)
递归的一般想法是一次处理一个令牌。
以下样式表:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="filename" name="tokenize">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="'_'"/>
<xsl:param name="token-names" select="'aa,bb,cc,dd,ee,ff'"/>
<xsl:element name="{substring-before($token-names, ',')}">
<xsl:value-of select="substring-before(concat($text, $separator), $separator)" />
</xsl:element>
<xsl:if test="contains($text, $separator)">
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $separator)"/>
<xsl:with-param name="token-names" select="substring-after($token-names, ',')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
将输出请求的结果。但请注意,令牌名称是从硬编码的字符串派生的,在此示例中,该字符串最多限制为6个令牌。
如果规定的限制有问题,您可以这样做:
<xsl:template match="filename" name="tokenize">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="'_'"/>
<xsl:param name="i" select="25"/>
<xsl:variable name="char">
<xsl:number value="$i" format="a"/>
</xsl:variable>
<xsl:element name="{concat($char, $char)}">
<xsl:value-of select="substring-before(concat($text, $separator), $separator)" />
</xsl:element>
<xsl:if test="contains($text, $separator)">
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $separator)"/>
<xsl:with-param name="i" select="$i + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
这将生成<aaaa>
作为<zz>
之后的令牌,依此类推。