2011-02-01 225 views
2

我有一些短格式的日期名稱,像這樣:轉換一週的縮寫形式天,一天名稱在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>

從評論雖然

的日子不會重複

+0

@StevenWilkins:可以在幾天反覆? – 2011-02-01 23:03:56

+0

@Alejandro - 天不會重複。 – StevenWilkins 2011-02-01 23:07:00

+0

您需要告訴我們這是XSLT 1.0還是2.0。在這個領域的問題總是比較容易的。 – 2011-02-01 23:59:42

回答

3

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> 

注意事項:因爲天不會重複,這與使用空字符串分隔符依次查找物品存在相同。

1

應該這樣做......(可能有更優雅的解決方案更新... ;-)

<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> 

1

目前接受的解決方案總是按時間順序顯示長天的名稱,此外,它不顯示重複(具有相同的代碼)天。

假設我們有下面的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>