我有一些短格式的日期名稱,像這樣:轉換一週的縮寫形式天,一天名稱在XSLT
M -> Monday
T -> Tuesday
W -> Wednesday
R -> Thursday
F -> Friday
S -> Saturday
U -> Sunday
我如何轉換像<days>MRF</days>
XML元素到使用XSLT長版<long-days>Monday,Thursday,Friday</long-days>
?
從評論雖然
的日子不會重複
我有一些短格式的日期名稱,像這樣:轉換一週的縮寫形式天,一天名稱在XSLT
M -> Monday
T -> Tuesday
W -> Wednesday
R -> Thursday
F -> Friday
S -> Saturday
U -> Sunday
我如何轉換像<days>MRF</days>
XML元素到使用XSLT長版<long-days>Monday,Thursday,Friday</long-days>
?
從評論雖然
的日子不會重複
This sty lesheet
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:d="day"
exclude-result-prefixes="d">
<d:d l="M" n="Monday"/>
<d:d l="T" n="Tuesday"/>
<d:d l="W" n="Wednesday"/>
<d:d l="R" n="Thursday"/>
<d:d l="F" n="Friday"/>
<d:d l="S" n="Saturday"/>
<d:d l="U" n="Sunday"/>
<xsl:variable name="vDays" select="document('')/*/d:d"/>
<xsl:template match="days">
<long-days>
<xsl:apply-templates
select="$vDays[contains(current(),@l)]"/>
</long-days>
</xsl:template>
<xsl:template match="d:d">
<xsl:value-of select="@n"/>
<xsl:if test="position()!=last()">,</xsl:if>
</xsl:template>
</xsl:stylesheet>
有了這個輸入:
<days>MRF</days>
輸出:
<long-days>Monday,Thursday,Friday</long-days>
編輯:對於那些誰徘徊,保留序列順序:
<xsl:variable name="vCurrent" select="current()"/>
<xsl:apply-templates
select="$vDays[contains($vCurrent,@l)]">
<xsl:sort select="substring-before($vCurrent,@l)"/>
</xsl:apply-templates>
注意事項:因爲天不會重複,這與使用空字符串分隔符依次查找物品存在相同。
應該這樣做......(可能有更優雅的解決方案更新... ;-)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/days">
<long-days>
<xsl:if test="contains(.,'M')">Monday<xsl:if test="string-length(substring-before(.,'M'))=string-length(.)-1">,</xsl:if></xsl:if>
<xsl:if test="contains(.,'T')">Tuesday<xsl:if test="string-length(substring-before(.,'T'))=string-length(.)-1">,</xsl:if></xsl:if>
<xsl:if test="contains(.,'W')">Wednesday<xsl:if test="string-length(substring-before(.,'W'))=string-length(.)-1">,</xsl:if></xsl:if>
<xsl:if test="contains(.,'R')">Thursday<xsl:if test="string-length(substring-before(.,'R'))=string-length(.)-1">,</xsl:if></xsl:if>
<xsl:if test="contains(.,'F')">Friday<xsl:if test="string-length(substring-before(.,'F'))=string-length(.)-1">,</xsl:if></xsl:if>
<xsl:if test="contains(.,'S')">Saturday<xsl:if test="string-length(substring-before(.,'S'))=string-length(.)-1">,</xsl:if></xsl:if>
<xsl:if test="contains(.,'U')">Sunday<xsl:if test="string-length(substring-before(.,'U'))=string-length(.)-1">,</xsl:if></xsl:if>
</long-days>
</xsl:template>
目前接受的解決方案總是按時間順序顯示長天的名稱,此外,它不顯示重複(具有相同的代碼)天。
假設我們有下面的XML文檔:
<days>STMSU</days>
一本XSLT 1.0轉換:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my" >
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:days>
<M>Monday</M>
<T>Tuesday</T>
<W>Wednesday</W>
<R>Thursday</R>
<F>Friday</F>
<S>Saturday</S>
<U>Sunday</U>
</my:days>
<xsl:key name="kLongByShort" match="my:days/*"
use="name()"/>
<xsl:variable name="vstylesheet"
select="document('')"/>
<xsl:template match="days">
<long-days>
<xsl:call-template name="expand"/>
</long-days>
</xsl:template>
<xsl:template name="expand">
<xsl:param name="pcodeString" select="."/>
<xsl:if test="$pcodeString">
<xsl:variable name="vchar" select=
"substring($pcodeString,1,1)"/>
<xsl:for-each select="$vstylesheet">
<xsl:value-of select=
"concat(key('kLongByShort',$vchar),
substring(',',1,string-length($pcodeString)-1)
)
"/>
</xsl:for-each>
<xsl:call-template name="expand">
<xsl:with-param name="pcodeString" select=
"substring($pcodeString,2)"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
當上述文件被應用時產生想要的,正確的結果:
<long-days>Saturday,Tuesday,Monday,Saturday,Sunday</long-days>
二,這個XSLT 2。0轉型:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:variable name="vshortCodes" as="xs:integer+"
select="string-to-codepoints('MTWRFSU')"/>
<xsl:variable name="vlongDays" as="xs:string+"
select="'Monday','Tuesday','Wenesday','Thursday',
'Friday','Saturday','Sunday'
"/>
<xsl:template match="days">
<long-days>
<xsl:for-each select="string-to-codepoints(.)">
<xsl:value-of separator="" select=
"for $pos in position() ne last()
return
($vlongDays[index-of($vshortCodes,current())],
','[$pos])
"/>
</xsl:for-each>
</long-days>
</xsl:template>
</xsl:stylesheet>
當在同一個XML文檔應用:
<days>STMSU</days>
產生想要的,正確的結果:
<long-days>Saturday,Tuesday,Monday,Saturday,Sunday</long-days>
@StevenWilkins:可以在幾天反覆? – 2011-02-01 23:03:56
@Alejandro - 天不會重複。 – StevenWilkins 2011-02-01 23:07:00
您需要告訴我們這是XSLT 1.0還是2.0。在這個領域的問題總是比較容易的。 – 2011-02-01 23:59:42