我是XSLT的新手,但不是XML.I需要转换此结构
Private Function DecodeError(ByVal error As Variant) As String
On Error Resume Next
Select Case CLng(error)
Case xlErrDiv0
DecodeError = "#DIV/0!"
Case xlErrNA
DecodeError = "#N/A"
Case xlErrName
DecodeError = "#NAME?"
Case xlErrNull
DecodeError = "#NULL!"
Case xlErrNum
DecodeError = "#NUM!"
Case xlErrRef
DecodeError = "#REF!"
Case xlErrValue
DecodeError = "#VALUE!"
Case Else
DecodeError = "Unknown error"
End Select
End Function
详细信息,成绩和年龄标记内的值使用CRLF分隔(分隔符)。
到
<Data>
<Details>Good
Bad
Normal
</Details>
<Grade>A
B
</Grade>
<Age>50
60
</Age>
</Data>
我开始知道没有split()函数,我们需要使用递归模板来分割字符串,但是我无法用头来创建所需的输出。
使用.net所以不支持XSLT 2.0。我知道我们可以使用像saxon这样的其他处理器,但我想用XSLT 1.0创建它。
或者,如果是其他任何方式,我也会考虑这一点。
任何帮助都将不胜感激。谢谢。
答案 0 :(得分:2)
这不是一个很好的解决方案,但更多的是为了表明(如何),即使没有任何扩展,也可以使用XSLT 1.0。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="Data">
<PersonDetails>
<xsl:apply-templates select="Details" />
</PersonDetails>
</xsl:template>
<xsl:template match="Details">
<xsl:call-template name="genDetails">
<xsl:with-param name="text" select="." />
<xsl:with-param name="pos" select="3" />
</xsl:call-template>
</xsl:template>
<xsl:template name ="genDetails">
<xsl:param name="text"/>
<xsl:param name="count" select="1" />
<xsl:param name="char" select="' '" />
<xsl:choose>
<xsl:when test="$text != '' ">
<Details>
<Type>
<xsl:value-of select="normalize-space(substring-before($text, $char))"/>
</Type>
<Grade>
<xsl:call-template name="gettext">
<xsl:with-param name="text" select="../Grade" />
<xsl:with-param name="pos" select="$count" />
<xsl:with-param name="char" select="$char" />
</xsl:call-template>
</Grade>
<Age>
<xsl:call-template name="gettext">
<xsl:with-param name="text" select="../Age" />
<xsl:with-param name="pos" select="$count" />
<xsl:with-param name="char" select="$char" />
</xsl:call-template>
</Age>
</Details>
<xsl:if test="contains($text, $char)">
<xsl:call-template name="genDetails">
<xsl:with-param name="text" select="substring-after($text, $char)" />
<xsl:with-param name="count" select="$count + 1" />
<xsl:with-param name="char" select="$char" />
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:text><!-- empty text --></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name ="gettext">
<xsl:param name="text"/>
<xsl:param name="pos" select="1" />
<xsl:param name="count" select="1" />
<xsl:param name="char" select="' '" />
<xsl:choose>
<xsl:when test="$count = $pos">
<xsl:value-of select="normalize-space(substring-before($text, $char))"/>
</xsl:when>
<xsl:when test="contains($text, $char)">
<xsl:call-template name="gettext">
<xsl:with-param name="text" select="substring-after($text, $char)" />
<xsl:with-param name="pos" select="$pos" />
<xsl:with-param name="count" select="$count + 1" />
<xsl:with-param name="char" select="$char" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:text><!-- empty text --></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
如果您不想迁移到XSLT 2.0处理器,那么请使用现有的库,例如EXSLT http://exslt.org/str/functions/tokenize/index.html:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:exsl="http://exslt.org/common"
xmlns:str="http://exslt.org/strings"
exclude-result-prefixes="msxsl exsl str">
<xsl:import href="http://exslt.org/str/functions/tokenize/str.tokenize.template.xsl"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Data">
<PersonDetails>
<xsl:variable name="det-rtf">
<xsl:call-template name="str:tokenize">
<xsl:with-param name="string" select="Details"/>
<xsl:with-param name="delimiters" select="' '"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="det" select="exsl:node-set($det-rtf)/token[normalize-space()]"/>
<xsl:variable name="grade-rtf">
<xsl:call-template name="str:tokenize">
<xsl:with-param name="string" select="Grade"/>
<xsl:with-param name="delimiters" select="' '"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="grade" select="exsl:node-set($grade-rtf)/token[normalize-space()]"/>
<xsl:for-each select="$det">
<xsl:variable name="pos" select="position()"/>
<Details>
<Type>
<xsl:value-of select="normalize-space()"/>
</Type>
<Grade>
<xsl:value-of select="normalize-space($grade[$pos])"/>
</Grade>
</Details>
</xsl:for-each>
</PersonDetails>
</xsl:template>
</xsl:stylesheet>
Age
元素的计算留给你练习。