2016-07-05 13 views
0

私は複数の属性を持つ以下のデータを持っています。 日時または時間帯の昇順で並べ替える必要があります。 入力に異なるDatetimeと同じTimezoneが含まれている場合は、Datetimeごとに昇順で出力されます。 入力に同じ日時と異なるタイムゾーンが含まれている場合は、タイムゾーンごとに昇順で出力する必要があります。xsl:複数の属性を並べ替え

現在のロジックは: -

<xsl:sort select="@Datetime" order="ascending"/> 
    <xsl:sort select="@Timezone" order="ascending"/> 

SAMPLEの第一のシナリオ出力が期待通りである:

<MSG> 
<DOC> 
<Parent> 
<Input Id="1234567890" Srvce="RRR" Cd="D1" Datetime="2016-06-16 20:42:30" Timezone="+02:00" EvtRmk="DUMMY 1"> 
</Input> 
<Input Id="1234567890" Srvce="RRR" Cd="D1" Datetime="2016-06-15 20:43:15" Timezone="+04:00" EvtRmk="DUMMY 1"> 
</Input> 

電流出力:

<Output>2016-06-15 20:43:15"</Output> 
    <Output>2016-06-16 20:42:30</Output> 

SAMPLE第二のシナリオ - 異なるタイムゾーン/同じ日時;出力は、タイムゾーンごとにソートされていない:

<MSG> 
</DOC> 
<Parent> 
<Input Id="1234567890" Srvce="RRR" Cd="D1" Datetime="2016-06-15 20:42:30" Timezone="+04:00" EvtRmk="DUMMY 1"> 
</Input> 
<Input Id="1234567890" Srvce="RRR" Cd="D1" Datetime="2016-06-15 20:43:15" Timezone="+00:00" EvtRmk="DUMMY 1"> 
</Input> 

電流出力:

<Output>2016-06-15 20:42:30</Output> 
<Output>2016-06-15 20:43:15</Output> 

予想される出力:XSLT 1.0

<Output>2016-06-15 20:43:15</Output> 
<Output>2016-06-15 20:42:30</Output> 
+0

はあなたが絶対的な時系列で並べ替えの結果をしたいと言っています注文?これは、すべてをUTCに最初に変換し、タイムスタンプでソートするのと同じです。 –

+0

はい、正しいです、それは時系列順にソートする必要があります。 –

+0

あなたの期待は根拠がありません。まずdatetimeでソートすると、 '2016-06-15 20:42:30'は常に' 2016-06-15 20:43:15'の前に来ます。セカンダリソートは、最初のソートで作成されたグループ内でのみ適用されます。 –

答えて

0

、あなたは、2回のパスでこれを実行する必要があります:最初の入力されたdateTimesをUTCなどの共通ベースに等しくして、結果をこの値でソートします。

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

<xsl:template match="Parent"> 
    <!-- first-pass --> 
    <xsl:variable name="inputs"> 
     <xsl:for-each select="Input"> 
      <input> 
       <xsl:copy-of select="@*"/> 
       <xsl:call-template name="dateTime-to-seconds"> 
        <xsl:with-param name="dateTime" select="@Datetime" /> 
        <xsl:with-param name="offset" select="@Timezone" /> 
       </xsl:call-template> 
      </input>  
     </xsl:for-each> 
    </xsl:variable> 
    <!-- output --> 
    <xsl:copy> 
     <xsl:for-each select="exsl:node-set($inputs)/input"> 
      <xsl:sort select="." data-type="number" order="ascending"/> 
      <Input> 
       <xsl:copy-of select="@*"/> 
      </Input> 
     </xsl:for-each> 
    </xsl:copy> 
</xsl:template> 

<xsl:template name="dateTime-to-seconds"> 
    <xsl:param name="dateTime"/> 
    <xsl:param name="offset"/> 

    <xsl:variable name="date" select="substring-before($dateTime, ' ')" /> 
    <xsl:variable name="local-time" select="substring-after($dateTime, ' ')" /> 

    <xsl:variable name="year" select="substring($date, 1, 4)" /> 
    <xsl:variable name="month" select="substring($date, 6, 2)" /> 
    <xsl:variable name="day" select="substring($date, 9, 2)" /> 

    <xsl:variable name="hour" select="substring($local-time, 1, 2)" /> 
    <xsl:variable name="minute" select="substring($local-time, 4, 2)" /> 
    <xsl:variable name="second" select="substring($local-time, 7)" /> 

    <xsl:variable name="offset-sign" select="1 - 2 * starts-with($offset, '-')" /> 
    <xsl:variable name="offset-hour" select="substring($offset, 2, 2) * $offset-sign" /> 
    <xsl:variable name="offset-minute" select="substring($offset, 5, 2) * $offset-sign" /> 

    <xsl:variable name="a" select="floor((14 - $month) div 12)"/> 
    <xsl:variable name="y" select="$year + 4800 - $a"/> 
    <xsl:variable name="m" select="$month + 12*$a - 3"/>  
    <xsl:variable name="jd" select="$day + floor((153*$m + 2) div 5) + 365*$y + floor($y div 4) - floor($y div 100) + floor($y div 400) - 32045" /> 

    <xsl:value-of select="86400*$jd + 3600*$hour + 60*$minute + $second - 3600*$offset-hour - 60*$offset-minute" /> 
</xsl:template> 

</xsl:stylesheet> 

次のテスト入力に印加さ:

XML

<Parent> 
    <Input Id="001" Datetime="2016-06-15 19:44:30" Timezone="-02:30"/> 
    <Input Id="002" Datetime="2016-06-15 20:42:30" Timezone="+04:00"/> 
    <Input Id="003" Datetime="2016-06-15 21:43:15" Timezone="+00:00"/> 
</Parent> 

結果は次のようになります。

<?xml version="1.0" encoding="UTF-8"?> 
<Parent> 
    <Input Id="002" Datetime="2016-06-15 20:42:30" Timezone="+04:00"/> 
    <Input Id="003" Datetime="2016-06-15 21:43:15" Timezone="+00:00"/> 
    <Input Id="001" Datetime="2016-06-15 19:44:30" Timezone="-02:30"/> 
</Parent> 
関連する問題