tags:

views:

39

answers:

2

Hi,

I have a tricky XSL problem at the moment. I need to copy the existing XML, copy a certain element (plus its child elements) and modify the value of two child-elements. The modifications are: divide value of the 'value' element by 110 and edit the value of the 'type' element from 'normal' to 'discount'.

This is currently what I have:

Current XML:

<dataset>
  <data>
   <prices>
    <price>
      <value>50.00</value>
      <type>normal</type>
    </price>
  </prices>
 </data>
</dataset>

Expected result

<dataset>
  <data>
   <prices>
    <price>
      <value>50.00</value>
      <type>normal</type>
    </price>
    <price>
      <value>45.00</value>
      <type>discount</type>
    </price>
  </prices>
 </data>
</dataset>

Any takers? I've gotten as far as copying the desired 'price' element using copy-of, but I'm stuck as to how to modify it next.

A: 

Assuming you have a template that matches price, you just need to add the logic you're talking about:

<xsl:template match="price">
  <!-- xsl:copy or xsl:copy-of depending on how you did it -->
  <xsl:copy>
    <xsl:apply-templates/>
  </xsl:copy>
  <price>
    <value>
      <xsl:value-of select="value * 0.9"/>
    </value>
    <type>discount</type>
  </price>
</xsl:template>

I'm guessing your operation is actually "multiply by .9" not "divide by 110" since 45 is not equal to 50 divided by 110 (nor is 45 equal to 50 divided by 1.10).

Welbog
+1  A: 

Your spec is a little off -- your value is the result of multiplying by .9, not dividing by 110. The below assumes you want to edit everything with a "normal" price -- change the template match pattern for your particular node or set of nodes.

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;

  <xsl:output method="xml"/>

  <xsl:template match="/dataset/data/prices/price[type='normal']">
    <xsl:apply-templates/>
    <xsl:copy>
      <value><xsl:value-of select="format-number(value * 0.9, '0.00')"/></value>
      <type>discount</type>
    </xsl:copy>
  </xsl:template>

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

</xsl:stylesheet>
Steven Huwig