2014-07-10 46 views
1

需要一些排序幫助,然後在XSLT中選擇最大值或最小值。在xslt中進行排序並選擇最小值或最大值

源XML:

<target> 
<relatedTarget> 
<permitExpiry>2005-07-02T08:11:00.000Z</permitExpiry> 
<permitStart>2015-07-11T09:22:00.000Z</permitStart> 
</relatedTarget> 

<relatedTarget> 
<permitExpiry>2003-07-12T08:11:00.000Z</permitExpiry> 
<permitStart>2014-07-01T09:22:00.000Z</permitStart> 
</relatedTarget> 

<relatedTarget> 
<permitExpiry>2002-07-10T08:11:00.000Z</permitExpiry> 
<permitStart>2016-07-06T09:22:00.000Z</permitStart> 
</relatedTarget> 
</target> 

結果XML:

<target> 
<relatedTarget> 
<permitStart>2014-07-01T09:22:00.000Z</permitStart> 
<permitExpiry>2005-07-02T08:11:00.000Z</permitExpiry> 
</relatedTarget> 
</target> 

基本上我需要的結果應該有最低permitStart日期和最大permitExpiry日期從所有正在添加日期間。

我的樣本XSL:

<xsl:template match="/"> 


<xsl:variable name="permitStartVar" select="//permitStart"/>   
<xsl:variable name="permitStopVar" select="//permitExpiry"/>   

<xsl:for-each select="relatedTask">  
<xsl:sort select="substring(permitStart,1,4)" /> <!-- Year --> 
<xsl:sort select="substring(permitStart,6,2)" /> <!-- Month --> 
<xsl:sort select="substring(permitStart,9,2)" /> <!-- Day --> 
<xsl:sort select="substring(permitStart,12,2)" /> <!-- Hour --> 
<xsl:sort select="substring(permitStart,15,2)" /> <!-- Minute --> 
<xsl:sort select="substring(permitStart,18,2)" /> <!-- Second --> 


<xsl:sort select="substring(permitExpiry,1,4)" /> <!-- Year --> 
<xsl:sort select="substring(permitExpiry,6,2)" /> <!-- Month --> 
<xsl:sort select="substring(permitExpiry,9,2)" /> <!-- Day --> 
<xsl:sort select="substring(permitExpiry,12,2)" /> <!-- Hour --> 
<xsl:sort select="substring(permitExpiry,15,2)" /> <!-- Minute --> 
<xsl:sort select="substring(permitExpiry,18,2)" /> <!-- Second --> 
</xsl:for-each> 

<target> 
<relatedTarget> 
<permitStart><xsl:value-of select="$permitStartVar[1]"/></permitStart> 
<permitExpiry><xsl:value-of select="$permitStopVar[last()]"/></permitExpiry> 
</relatedTarget>  
</target> 

</template> 
+0

請發佈您的實際示例xsl和xml,因爲既不是實際有效的xml或xsl,也不是您想要的輸出!對於排序,你不必像這樣分割它,如果你只是按照permitStart進行排序,你應該得到相同的結果,因爲日期字符串已經與分解時的順序相同。 –

+0

您使用的是像Saxon 9這樣的XSLT 2.0處理器嗎?然後簡單地在'xs:dateTime(permitExpiry)'上進行排序,因爲XSLT 2.0支持那個xs:dateTime數據類型。 –

回答

1

當我按照你的方法,

<xsl:stylesheet exclude-result-prefixes="xs" version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:template match="target"> 
    <xsl:variable name="permitStartVar" select="//permitStart"/> 
    <xsl:variable name="permitStopVar" select="//permitExpiry"/> 
    <xsl:variable name="temp"> 
    <xsl:for-each select="relatedTarget/permitStart"> 
     <xsl:sort select="substring(permitStart,1,4)"/> 
     <!--Year--> 
     <xsl:sort select="substring(permitStart,6,2)"/> 
     <!--Month--> 
     <xsl:sort select="substring(permitStart,9,2)"/> 
     <!--Day--> 
     <xsl:sort select="substring(permitStart,12,2)"/>   <!--Hour--> 
     <xsl:sort select="substring(permitStart,15,2)"/> 
     <!--Minute--> 
     <xsl:sort select="substring(permitStart,18,2)"/> 
     <!--Second--> 
     <xsl:copy-of select="."/> 
    </xsl:for-each> 
    </xsl:variable> 
    <xsl:variable name="temp1"> 
    <xsl:for-each select="relatedTarget/permitExpiry"> 
     <xsl:sort select="substring(permitExpiry,1,4)" order="descending"/> 
     <!--Year--> 
     <xsl:sort select="substring(permitExpiry,6,2)" order="descending"/> 
     <!--Month--> 
     <xsl:sort select="substring(permitExpiry,9,2)" order="descending"/> 
     <!--Day--> 
     <xsl:sort select="substring(permitExpiry,12,2)" order="descending"/> 
     <!--Hour--> 
     <xsl:sort select="substring(permitExpiry,15,2)" order="descending"/> 
     <!--Minute--> 
     <xsl:sort select="substring(permitExpiry,18,2)" order="descending"/> 
     <!--Second--> 
     <xsl:copy-of select="."/> 
    </xsl:for-each> 
    </xsl:variable> 
    <target> 
    <relatedTarget> 
     <permitStart> 
      <xsl:value-of select="$temp//permitStart[1]"/> 
     </permitStart> 
     <permitExpiry> 
      <xsl:value-of select="$temp1/permitExpiry[1]"/> 
     </permitExpiry> 
    </relatedTarget> 
    </target> 
</xsl:template> 
</xsl:stylesheet> 

輸出:

<target> 
<relatedTarget> 
    <permitStart>2014-07-01T09:22:00.000Z</permitStart> 
    <permitExpiry>2003-07-12T08:11:00.000Z</permitExpiry> 
</relatedTarget> 
</target> 

編輯:

更簡化的版本:

<xsl:stylesheet exclude-result-prefixes="xs" version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:template match="target"> 
    <xsl:variable name="permitStartVar" select="//permitStart"/> 
    <xsl:variable name="permitStopVar" select="//permitExpiry"/> 

    <xsl:variable name="temp"> 
    <xsl:for-each select="relatedTarget/permitStart"> 
     <xsl:sort select="."/> 
     <xsl:copy-of select="."/> 
    </xsl:for-each> 
    </xsl:variable> 
    <xsl:variable name="temp1"> 
    <xsl:for-each select="relatedTarget/permitExpiry"> 
     <xsl:sort select="." order="descending"/> 
     <xsl:copy-of select="."/> 
    </xsl:for-each> 
    </xsl:variable> 
    <target> 
    <relatedTarget> 
     <permitStart> 
      <xsl:value-of select="$temp//permitStart[1]"/> 
     </permitStart> 
     <permitExpiry> 
      <xsl:value-of select="$temp1/permitExpiry[1]"/> 
     </permitExpiry> 
    </relatedTarget> 
    </target> 
</xsl:template> 
</xsl:stylesheet> 
+1

您輸出中的'permitExpiry'不正確。 –

+0

感謝您的觀察。更正了錯誤 –

+1

不客氣。 +1 –

2

你能做到這一點,而不使用在xs:dateTimemax()min()排序。

XML輸入

<target> 
    <relatedTarget> 
     <permitExpiry>2005-07-02T08:11:00.000Z</permitExpiry> 
     <permitStart>2015-07-11T09:22:00.000Z</permitStart> 
    </relatedTarget> 

    <relatedTarget> 
     <permitExpiry>2003-07-12T08:11:00.000Z</permitExpiry> 
     <permitStart>2014-07-01T09:22:00.000Z</permitStart> 
    </relatedTarget> 

    <relatedTarget> 
     <permitExpiry>2002-07-10T08:11:00.000Z</permitExpiry> 
     <permitStart>2016-07-06T09:22:00.000Z</permitStart> 
    </relatedTarget> 
</target> 

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 indent="yes"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="/*"> 
     <target> 
      <relatedTarget> 
       <xsl:copy-of select="(relatedTarget/permitStart[.=min(/*/relatedTarget/xs:dateTime(permitStart))])[1]"/> 
       <xsl:copy-of select="(relatedTarget/permitExpiry[.=max(/*/relatedTarget/xs:dateTime(permitExpiry))])[1]"/> 
      </relatedTarget> 
     </target> 
    </xsl:template> 

</xsl:stylesheet> 

輸出

<target> 
    <relatedTarget> 
     <permitStart>2014-07-01T09:22:00.000Z</permitStart> 
     <permitExpiry>2005-07-02T08:11:00.000Z</permitExpiry> 
    </relatedTarget> 
</target> 
+0

感謝丹尼爾,此解決方案僅適用於XSLT版本2.0。 – SunDante

+0

@SunDante - 這是正確的,因爲你的問題被標記爲xslt-2.0,它應該適合你。如果此問題僅適用於1.0,請更新標籤。 –

相關問題