我正在尝试将分隔符分隔的数据转换为tokenize并使用xsl解析为xml。目前我有这个
XML
abc|"x|y|z"|gh|ij
XSL
<xsl:template match="/">
<client:SplitString>
<xsl:call-template name="tokenize">
<xsl:with-param name="text"
select="/client:CSVString/client:CSV_Value"/>
</xsl:call-template>
</client:SplitString>
</xsl:template>
<xsl:template match="text/text()" name="tokenize">
<xsl:param name="text" select="$text"/>
<xsl:param name="separator"
select="|"/>
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
<client:Value>
<xsl:value-of select="normalize-space($text)"/>
</client:Value>
</xsl:when>
<xsl:otherwise>
<client:Value>
<xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
</client:Value>
<xsl:call-template name="tokenize">
<xsl:with-param name="text"
select="substring-after($text, $separator)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
这适用于常规分隔符分隔值,但在分隔符内的管道上失败。我有正则表达式,它可以将引号内的管道识别为单个值。但我不知何故无法使用它。
"([^"]*)",?|([^|]+),?
我希望结果是
<result>abc</result>
<result>x|y|z</result>
<result>gh</result>
<result>ij</result>
任何形式的帮助将不胜感激。谢谢!
答案 0 :(得分:2)
您可以做的是检查要标记的字符串是否以引号开头。如果是,输出引号之间的内容。如果没有,请正常标记。
示例...
XML输入
<doc>
<value>abc|"x|y|z"|gh|ij</value>
<value>"x|y|z"|abc|gh|ij</value>
<value>abc|"x|y|z"|gh|"x|y|z"|ij</value>
<value>"x|y|z"|abc|"x|y|z"|gh|ij|"x|y|z"</value>
</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="value">
<SplitString>
<xsl:call-template name="tokenize">
<xsl:with-param name="input" select="normalize-space()"/>
</xsl:call-template>
</SplitString>
</xsl:template>
<xsl:template name="tokenize">
<xsl:param name="delimiter" select="'|'"/>
<xsl:param name="input"/>
<xsl:choose>
<xsl:when test="starts-with($input, '"')">
<xsl:variable name="value" select="substring-before(substring-after($input,'"'),'"')"/>
<result>
<xsl:value-of select="normalize-space($value)"/>
</result>
<xsl:call-template name="tokenize">
<xsl:with-param name="input" select="normalize-space(substring($input,string-length($value)+3))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="value" select="substring-before(concat($input,$delimiter),$delimiter)"/>
<xsl:if test="string($value)">
<result>
<xsl:value-of select="normalize-space($value)"/>
</result>
</xsl:if>
<xsl:if test="string(substring-after($input,$delimiter))">
<xsl:call-template name="tokenize">
<xsl:with-param name="input" select="normalize-space(substring-after($input,$delimiter))"/>
</xsl:call-template>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
<SplitString>
<result>abc</result>
<result>x|y|z</result>
<result>gh</result>
<result>ij</result>
</SplitString>
<SplitString>
<result>x|y|z</result>
<result>abc</result>
<result>gh</result>
<result>ij</result>
</SplitString>
<SplitString>
<result>abc</result>
<result>x|y|z</result>
<result>gh</result>
<result>x|y|z</result>
<result>ij</result>
</SplitString>
<SplitString>
<result>x|y|z</result>
<result>abc</result>
<result>x|y|z</result>
<result>gh</result>
<result>ij</result>
<result>x|y|z</result>
</SplitString>