1

I have been tasked with building an XSLT file using a specific set of XML. The only problem is I have never used XSLT or XML. I have been digging through it for the last few hours and have hit my first real roadblock.

I need to return or print a value based on a given attribute in a specific XML node.

XML:

<Numbers>
    <Products productCode="RSD">
        <Value>54.99</Value>
        <Value>12.35</Value>
        <Value>8.00</Value>
        <Value>9.99</Value>
    </Products>
</Numbers>

I need my XSLT transform to produce a heading based on the productCode attribute (so that it can be placed in a table for better legibility). I am a JavaScript developer so in essence I am looking for the equivalent of

if(productCode === "RSD"){
    this.html("Product Heading");
}

I am completely out of my comfort zone here so any tips/pointers/advice is greatly appreciated.

Thank You!

3
  • 1
    What do you plan to do with the values? Place them in a table? Commented May 24, 2014 at 16:13
  • Yes, I plan on placing them in a table. The goal is to make our feed more legible. Commented May 24, 2014 at 16:15
  • 1
    I provided an example. You might be able to use it as a starting point. Commented May 24, 2014 at 16:27

1 Answer 1

1

If you apply your source XML to this stylesheet:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>

    <xsl:template match="Products[@productCode='RSD']">
        <h1>Product Heading</h1>
        <table border='1'>
            <xsl:apply-templates select="Value"/>
        </table>
    </xsl:template>

    <xsl:template match="Value">
        <tr><td><xsl:value-of select="."/></td></tr>
    </xsl:template>

</xsl:stylesheet>

It will generate this HTML fragment:

<h1>Product Heading</h1>
<table border="1">
   <tr>
      <td>54.99</td>
   </tr>
   <tr>
      <td>12.35</td>
   </tr>
   <tr>
      <td>8.00</td>
   </tr>
   <tr>
      <td>9.99</td>
   </tr>
</table>

The first template uses an XPath expression to match the nodes you are interested in. The contents of the template describe the structure of your result tree. <xsl:apply-templates/> recursively processes the rest of the tree, and if it finds any matching templates it will process them. It uses a relative XPath expression Value to select the nodes named <Value> in the current context (which is <Product>), and will process all four of them. The second template matches that selection and generates the <tr><td> nodes. <xsl:value-of> simply prints the string-value of the nodes (the XPath expression . selects the node in the current context, which in the second template is <Value>.

You can verify and experiment with your example in this Fiddle

Sign up to request clarification or add additional context in comments.

7 Comments

This is fantastic and is a huge help in the right direction. I imagine I will run into one or two more snags along the way so I may post a few more comments on here as the day goes by. Thanks for your help.
Question: How do I format-number on the XPath expression "."? Right now I am attempting to convert the values to a percentage so that 54.99 becomes 59.44%. I have attempted to use: <tr><td><xsl:value-of select="format-number(.,"%")"/></td></tr>
If you just need to add the % you can simply place it as text, outside the select: <td><xsl:value-of select="."/>%</td>. You can use format-number to control the number of digits after the decimal point, and to multiply it by 100 (if you include a % inside it), but your data is already formatted, so it's not necessary.
Ah of course how simple.. I have clearly been looking at this too long.
term[@length] prints the value of all the term elements in the current context that have a length attribute (containing any value). term/@length prints the value of the length attribute of the first term element in the context (if there is only one, it's what you want; if there are many elements in the context, and you want to select attributes from the others as well, you can use term[1]/@length, term[2]/@length, etc.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.