[英]How to transform the XML structure using XSLT 1.0
我对XSLT非常陌生,但对XML则不是。我需要转换这种结构
<Data>
<Details>Good
Bad
Normal
</Details>
<Grade>A
B
</Grade>
<Age>50
60
</Age>
</Data>
使用CRLF分隔“详细信息”,“成绩”和“年龄”标签中的值(定界符)。
成
<PersonDetails>
<Details>
<Type>Good</Type>
<Grade>A</Grade>
<Age>50</Age>
</Details>
<Details>
<Type>Bad</Type>
<Grade>B</Grade>
<Age>60</Age>
</Details>
<Details>
<Type>Normal</Type>
<Grade></Grade>
<Age></Age>
</Details>
</PersonDetails>
我知道没有split()函数,我们需要使用递归模板来拆分字符串,但是无法包扎头来创建所需的输出。
我正在使用.net,因此不支持XSLT 2.0。我知道我们可以使用其他处理器,例如saxon,但是我想使用XSLT 1.0创建它。
或者,如果还有其他方式,我也会考虑。
任何帮助将不胜感激。谢谢。
这不是一个很好的解决方案,而是更多地证明了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>
如果您不想转移到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
元素的计算留给您作为练习。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.