masay
masay

Reputation: 933

how to set a new value to variable or param in xsl

I need some help about xsl. I have a date attribute in source xml and i need to know its previous value because i need categorized according to date. here is the source xml.

source xml:

<root>
  <license id="a" expireDate="2010-02-01"/>
  <license id="b" expireDate="2010-02-01"/>
  <license id="c" expireDate="2010-02-01"/>
  <license id="d" expireDate="2010-02-04"/>
  <license id="e" expireDate="2010-02-04"/>
  <license id="f" expireDate="2010-02-12"/>
  <license id="g" expireDate="2010-02-12"/>
</root>

I need to transform this to

<licenses>
   <expDate value="2010-02-01">
      <license>a</license>
      <license>b</license>
      <license>c</license>
   </expDate>
   <expDate value="2010-02-04">
      <license>d</license>
      <license>e</license>
   </expDate>
   <expDate value="2010-02-12">
      <license>f</license>
      <license>g</license>
   </expDate>
</licenses>

Actually, i can transform source xml which have different format from the given one. I have read some articles but could not find the way to do this. How can I keep the previous date value and check if its different from current one.

Thanks

Upvotes: 3

Views: 3973

Answers (1)

Wayne
Wayne

Reputation: 60414

You can't change the value of a variable in XSLT, but you don't need to. The following stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="byDate" match="license" use="@expireDate" />
    <xsl:template match="/">
        <licenses>
            <xsl:apply-templates />
        </licenses>
    </xsl:template>
    <xsl:template
        match="license[generate-id() = 
                       generate-id(key('byDate', @expireDate)[1])]">
        <expDate value="{@expireDate}">
            <xsl:apply-templates select="key('byDate', @expireDate)"
                mode="group" />
        </expDate>
    </xsl:template>
    <xsl:template match="license" mode="group">
        <license>
            <xsl:value-of select="@id" />
        </license>
    </xsl:template>
    <xsl:template match="license" />
</xsl:stylesheet>

Applied to this input:

<root>
  <license id="a" expireDate="2010-02-01"/>
  <license id="b" expireDate="2010-02-01"/>
  <license id="c" expireDate="2010-02-01"/>
  <license id="d" expireDate="2010-02-04"/>
  <license id="e" expireDate="2010-02-04"/>
  <license id="f" expireDate="2010-02-12"/>
  <license id="g" expireDate="2010-02-12"/>
</root>

Produces the following output:

<licenses>
    <expDate value="2010-02-01">
        <license>a</license>
        <license>b</license>
        <license>c</license>
    </expDate>
    <expDate value="2010-02-04">
        <license>d</license>
        <license>e</license>
    </expDate>
    <expDate value="2010-02-12">
        <license>f</license>
        <license>g</license>
    </expDate>
</licenses>

Note: Your original XML was not well-formed. I moved the license value to an id attribute.

Upvotes: 5

Related Questions