2016-04-16 71 views
1

我有一個下面的XML結構,我想對日期進行排序並將一個日期節點更新到最新日期。日期爲YYYY/mm/dd格式。以下是XML結構。如何在XSL中對日期進行排序?

更具體地說,我在下面舉一個例子。 假設有3個覆蓋生效日期2015/01/01,2015/01/02,2015/01/03,那麼customerEffectiveDate應更新至2015/01/03。

有關XML結構的注意事項: 1.產品數量可以從1到10. 2.覆蓋節點可以從1到多。

<Map> 
    <customer> 
     <customerDetails> 
      <!-- The customerEffectiveDate below should be updated to the latest among all the effectiveDate fron coverage.--> 
      <customerEffectiveDate>2014/06/02</customerEffectiveDate> 
     </customerDetails> 
    </customer> 
    <products> 
     <product1> 
      <!-- Coverage Nodes can occur multiple times. There is no limit.--> 
      <coverage> 
       <effectiveDate>2015/12/01</effectiveDate> 
      </coverage> 
      <coverage> 
       <effectiveDate>2015/11/01</effectiveDate> 
      </coverage> 
     </product1> 
     <product2> 
      <coverage> 
       <effectiveDate>2014/12/01</effectiveDate> 
      </coverage> 
      <coverage> 
       <effectiveDate>2015/09/01</effectiveDate> 
      </coverage> 
     </product2> 
     . 
     . 
     . 
     . 
     . 
     . 
     . 
     . 

     <product10></product10> 
    </products> 
</Map> 

另一點需要注意的是我使用的是XSL 1.0。有人可以請幫助。

我已經看過this,thisthis

謝謝。

回答

1

鑑於格式,你可以很容易地對它進行排序,編寫模板

<xsl:template match="customer/customerDetails/customerEffectiveDate"> 
    <xsl:copy> 
    <xsl:for-each select="//coverage/effectiveDate"> 
     <xsl:sort select="." data-type="text" order="descending"/> 
     <xsl:if test="position() = 1"> 
     <xsl:value-of select="."/> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:copy> 
</xsl:template> 

加上身份轉換模板

<xsl:template match="@* | node()"> 
    <xsl:copy> 
    <xsl:apply-templates select="@* | node()"/> 
    </xsl:copy> 
</xsl:template> 

複製其餘不變。

+0

條件會做什麼?什麼是「身份轉換模板」? – Sam

+0

我已編輯代碼以顯示身份轉換模板的外觀。至於檢查,那麼代碼按降序排序,然後取第一個值,最後一個日期,並輸出它。 –

1

這可能不是最簡單的方式,但是這種方式下<product1-10>標籤排序的所有<coverage>標籤,提取從所有<effectiveDate>值及複印件,其餘的最新值。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<!-- Process <products> tag with higher priority, so that the follwing template does not match --> 
<xsl:template match="products" priority="1"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[starts-with(local-name(),'product')]"> 
    <xsl:element name="{name()}"> 
    <xsl:for-each select="coverage"> 
     <xsl:sort select="effectiveDate/text()" order="descending" /> 
     <xsl:copy-of select="." /> 
    </xsl:for-each> 
    </xsl:element> 
</xsl:template> 

<!-- extract the first 'effectiveDate' after sorting all values --> 
<xsl:template match="customerEffectiveDate"> 
    <xsl:variable name="latest"> 
    <xsl:for-each select="../../../products//effectiveDate"> 
     <xsl:sort select="text()" order="descending" /> 
     <xsl:if test="position() = 1"> 
     <xsl:value-of select="." /> 
     </xsl:if> 
    </xsl:for-each> 
    </xsl:variable> 
    <customerEffectiveDate><xsl:copy-of select="$latest" /></customerEffectiveDate> 
</xsl:template> 

</xsl:stylesheet> 
相關問題