M.I.T.
M.I.T.

Reputation: 1042

Issue During creating XSL file from XML

I have a table structure like this:

id name parent_id
1 root_category Null
2 Appare 1
3 Accessories 1
4 Shirt 2
5 Pants 2
6 hand Bags 3
7 jewelry 3

from this table I have created a XML file which is like this test.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<childrens>
  <child id="1" value="Root Catalog" parent_id="0">
    <child id="2" value="Apparel" parent_id="1">
      <child id="4" value="Shirts" parent_id="2"/>
      <child id="5" value="Pants" parent_id="2"/>
    </child>
    <child id="3" value="Accessories" parent_id="1">
      <child id="6" value="Handbags" parent_id="3"/>
      <child id="7" value="Jewelry" parent_id="3"/>
    </child>
  </child>
</childrens>

using this xml file i have created a XSL file which is like this test.xsl

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<html>
<body>
<h2>Testing</h2>
  <table border="1">
   <tr bgcolor="#9acd32">
    <th>Id </th>
    <th>Name</th>
  </tr>
  <xsl:for-each select="childrens/child">
  <tr>
    <td><xsl:value-of select="@id"/></td>
    <td><xsl:value-of select="@value"/></td>
  </tr>
  </xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

but it is not working and it is not showing data

data should look like

Root Category
 - Apparel 
   -- Shirts
   -- Pants 
 - Accessories
   -- Handbags 
  -- Jewelry

Upvotes: 0

Views: 171

Answers (2)

Peter
Peter

Reputation: 1796

I tried to do an XSLT that does a text output. I have added Line feeds and Tab to get the structure requested. I would strongly recommend to change your XML though and name the elements something different than child, it would be easier to work with in my opinion. But that is just a recommendation.

Apply this XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:output method="text"/>

<xsl:variable name="lf" select="'&#x0A;'"/>
<xsl:variable name="tab" select="'&#x09;'"/>

<xsl:template match="/">
    <xsl:text>Root Category</xsl:text>
    <xsl:apply-templates/>
</xsl:template>

<!-- match the apparel -->
<xsl:template match="child[@value='Apparel']">
    <xsl:value-of select="concat('-- ',@value)"/>
    <xsl:value-of select="$lf"/>
    <xsl:apply-templates select="child" mode="apparel"/>
</xsl:template>
<!-- match the child elements of apparel -->
<xsl:template match="child" mode="apparel">
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="concat('- ',./@value)"/>
    <xsl:value-of select="$lf"/>
</xsl:template>

<!-- match the accessories -->
<xsl:template match="child[@value='Accessories']">
    <xsl:value-of select="concat('-- ',@value)"/>
    <xsl:value-of select="$lf"/>
    <xsl:apply-templates select="child" mode="accessories"/>
</xsl:template>
<!-- match the child elements of accessories -->
<xsl:template match="child" mode="accessories">
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="$tab"/>
    <xsl:value-of select="concat('- ',./@value)"/>
    <xsl:value-of select="$lf"/>
</xsl:template>



</xsl:stylesheet>

to this XML input:

<?xml version="1.0" encoding="ISO-8859-1"?>
<childrens>
<child id="1" value="Root Catalog" parent_id="0">
    <child id="2" value="Apparel" parent_id="1">
        <child id="4" value="Shirts" parent_id="2"/>
        <child id="5" value="Pants" parent_id="2"/>
    </child>
    <child id="3" value="Accessories" parent_id="1">
        <child id="6" value="Handbags" parent_id="3"/>
        <child id="7" value="Jewelry" parent_id="3"/>
    </child>
</child>
</childrens>

and you get this output:

Root Category

    -- Apparel
        - Shirts
        - Pants

    -- Accessories
        - Handbags
        - Jewelry

Upvotes: 1

Tim C
Tim C

Reputation: 70648

I am not entirely sure what output you are expecting. Your current XSLT is outputing a table, but your example looks more like nested lists. If you did want to show the hierarchy structure of your elements, then nested lists would probably be the way to go.

This would be relatively straight-forward to achieve by means of a single template to match child elements, which then recursively called itself.

   <xsl:template match="child">
      <li>
         <xsl:value-of select="@value"/>
         <xsl:if test="child">
            <ul>
               <xsl:apply-templates select="child"/>
            </ul>
         </xsl:if>
      </li>
   </xsl:template>

i.e. Output a li element, and then start a new ul element within this if the element itself has children.

Here is the full XSLT

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

   <xsl:template match="/childrens">
      <html>
         <body>
            <ul>
               <xsl:apply-templates select="child"/>
            </ul>
         </body>
      </html>
   </xsl:template>

   <xsl:template match="child">
      <li>
         <xsl:value-of select="@value"/>
         <xsl:if test="child">
            <ul>
               <xsl:apply-templates select="child"/>
            </ul>
         </xsl:if>
      </li>
   </xsl:template>
</xsl:stylesheet>

When applied to your sample XML, the following is output

<html>
   <body>
      <ul>
         <li>Root Catalog
            <ul>
               <li>Apparel
                  <ul>
                     <li>Shirts</li>
                     <li>Pants</li>
                  </ul>
               </li>
               <li>Accessories
                  <ul>
                     <li>Handbags</li>
                     <li>Jewelry</li>
                  </ul>
               </li>
            </ul>
         </li>
      </ul>
   </body>
</html>

Which visually will appear as follows

  • Root Catalog
    • Apparel
      • Shirts
      • Pants
    • Accessories
      • Handbags
      • Jewelry

EDIT: As mentioned by JLRishie in the comment (Thanks!), if you want to include the ID attribute on the li elements, do the following:

<li id="{@id}">

Upvotes: 1

Related Questions