XSLT 1.0: Sorting by specifying parts of a date string

I am trying to take the XML data and sort the elements by their data attribute. Unfortunately, dates are in the format mm / dd / yyyy and are not static. (Jan = 1 instead of 01). Therefore, I believe that the line should be analyzed for three components, and the month is full. Then the new value (yyyymmdd) is sorted in descending order.

The problem is that I have no idea how to do this. Below is sample data

<content date="1/13/2011 1:21:00 PM">
    <collection vo="promotion">
        <data vo="promotion" promotionid="64526" code="101P031" startdate="1/7/2011 12:00:00 AM" type="base"/>
        <data vo="promotion" promotionid="64646" code="101P026" startdate="2/19/2011 12:00:00 AM" type=""/>
        <data vo="promotion" promotionid="64636" code="101P046" startdate="1/9/2011 12:00:00 AM" type="base"/>
    </collection>
</content>

Also can anyone recommend a good XSLT training book?

Thank!

Update 1

, LOL. , "", , , . , , .

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

    <xsl:template match="/">
      <xsl:variable name="vrtfPass1">
        <xsl:apply-templates/>
      </xsl:variable>
      <xsl:apply-templates mode="pass2" select=
       "ext:node-set($vrtfPass1)/*"/>
    </xsl:template>

    <xsl:template match="@startdate">
     <xsl:variable name="vDate" select="substring-before(.,' ')"/>

     <xsl:variable name="vYear" select=
       "substring($vDate, string-length($vDate) -3)"/>
     <xsl:variable name="vDayMonth" select=
      "substring-before($vDate, concat('/',$vYear))"/>

      <xsl:variable name="vMonth"
        select="format-number(substring-before($vDayMonth, '/'), '00')"/>
      <xsl:variable name="vDay"
        select="format-number(substring-after($vDayMonth, '/'), '00')"/>

    <xsl:attribute name="startdate">
      <xsl:value-of select="concat($vYear,$vMonth,$vDay)"/>
    </xsl:attribute>
    </xsl:template>

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

    <xsl:template mode="pass2" match="collection">
      <xsl:copy>
       <xsl:apply-templates mode="pass2" select="@*"/>
       <xsl:apply-templates mode="pass2">
        <xsl:sort select="@startdate"/>
       </xsl:apply-templates>
      </xsl:copy>
    </xsl:template>

    <xsl:template match="content/collection/data">
        <xsl:if test="position()=1">
                   <xsl:value-of select="@promotionid"/>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

2

, , ,

...
</xsl:template>

    <xsl:template mode="pass2" match="content/collection/data">
                   <xsl:value-of select="@promotionid"/>
    </xsl:template>
</xsl:stylesheet>

. , xmlns:ext="http://exslt.org/common" , .

. , - xslt .

3

, -, , , . XML , , .

, , , propid node, = 'base'. node = 'base', node, .

, . .

+1
2

xsl:sort, :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="collection">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="data">
            <xsl:sort select="substring-after(
                                 substring-after(
                                    substring-before(
                                       @startdate,
                                       ' '),
                                    '/'),
                                 '/')" data-type="number"/>
            <xsl:sort select="substring-before(
                                 @startdate,
                                 '/')" data-type="number"/>
            <xsl:sort select="substring-before(
                                 substring-after(
                                    @startdate,
                                    '/'),
                                 '/')" data-type="number"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

:

<content date="1/13/2011 1:21:00 PM">
    <collection vo="promotion">
        <data vo="promotion" promotionid="64526" code="101P031"
              startdate="1/7/2011 12:00:00 AM"></data>
        <data vo="promotion" promotionid="64636" code="101P046"
              startdate="1/9/2011 12:00:00 AM"></data>
        <data vo="promotion" promotionid="64646" code="101P026"
              startdate="2/19/2011 12:00:00 AM"></data>
    </collection>
</content>

, , , '2/19/2011' . - <xsl:value-of select="data[last()]/@promotionid"/>

3:

"" . :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="collection">
        <xsl:variable name="vData" select="data[@type='base']"/>
        <xsl:for-each select="data[not($vData)]|$vData">
            <xsl:sort select="substring-after(
                                     substring-after(
                                        substring-before(
                                           @startdate,
                                           ' '),
                                        '/'),
                                     '/')" data-type="number"/>
            <xsl:sort select="substring-before(
                                     @startdate,
                                     '/')" data-type="number"/>
            <xsl:sort select="substring-before(
                                     substring-after(
                                        @startdate,
                                        '/'),
                                     '/')" data-type="number"/>
            <xsl:if test="position()=last()">
                <xsl:value-of select="@promotionid"/>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

:

64636
+1

( , ):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

    <xsl:template match="/">
      <xsl:variable name="vrtfPass1">
        <xsl:apply-templates/>
      </xsl:variable>
      <xsl:apply-templates mode="pass2" select=
       "ext:node-set($vrtfPass1)/*"/>
    </xsl:template>

    <xsl:template match="@startdate">
     <xsl:variable name="vDate" select="substring-before(.,' ')"/>

     <xsl:variable name="vYear" select=
       "substring($vDate, string-length($vDate) -3)"/>
     <xsl:variable name="vDayMonth" select=
      "substring-before($vDate, concat('/',$vYear))"/>

      <xsl:variable name="vMonth"
        select="format-number(substring-before($vDayMonth, '/'), '00')"/>
      <xsl:variable name="vDay"
        select="format-number(substring-after($vDayMonth, '/'), '00')"/>

    <xsl:attribute name="startdate">
      <xsl:value-of select="concat($vYear,$vMonth,$vDay)"/>
    </xsl:attribute>
    </xsl:template>

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

    <xsl:template mode="pass2" match="collection">
      <xsl:copy>
       <xsl:apply-templates mode="pass2" select="@*"/>
       <xsl:apply-templates mode="pass2">
        <xsl:sort select="@startdate"/>
       </xsl:apply-templates>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

, XML-:

<content date="1/13/2011 1:21:00 PM">
    <collection vo="promotion">
        <data vo="promotion" promotionid="64526" code="101P031" startdate="1/7/2011 12:00:00 AM"/>
        <data vo="promotion" promotionid="64646" code="101P026" startdate="2/19/2011 12:00:00 AM"/>
        <data vo="promotion" promotionid="64636" code="101P046" startdate="1/9/2011 12:00:00 AM"/>
    </collection>
</content>

, :

<content date="1/13/2011 1:21:00 PM">
   <collection vo="promotion">
      <data vo="promotion" promotionid="64526" code="101P031" startdate="20110107"/>
      <data vo="promotion" promotionid="64636" code="101P046" startdate="20110109"/>
      <data vo="promotion" promotionid="64646" code="101P026" startdate="20110219"/>
   </collection>
</content>

:

  • Multipass XSLT 1.0 xxx:node-set(), , RTF (Fragment of Transformation Fragment) ().

  • xxx:node-set(), , - ext:node-set() EXSLT, XSLT-.

0

All Articles