[英]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.