Pradep
Pradep

Reputation: 2024

How to use xslt with attribute values as selectors ?

I am trying to learn xslt and i am working an xml which looks like this.

<Beats>
 <Beat>
   <Personal type="set">
      <Usages type="box">
       1233
      </Usages>
      <NonUsages type="box">
       4122
      </NonUsages>
   </Personal>

   <NonPersonal type="unset">
      <Damages type="box">
       6466
      </Damages>
      <NonDamages type="box">
       5544
      </NonUsages>
   </NonPersonal>

   <Confidential type="set">
      <Discounts type="box">
       1233
      </Discounts>
      <NonDiscounts type="box">
       4122
      </NonDiscounts>
   </Confidential>

 </Beat>
</Beats>

My Current aim is to just print out the numbers inside the inner tags. But i cannot use the names of the tags as selectors as only the attribute 'type'is of importance. I tried using the following xslt. But it didnt seem to work.

<xsl:output method="text"/>
<xsl:template match="*">
<html>
<body>
<h2> Test</h2>
<xsl:for-each select="//Beats/Beat/[@type='set']">
   <xsl:value-of select="[@type='box'] />
   <br/>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

What am i doing wrong ?

And one more thing i couldnt figure out was how to get the name of tags while using attributes as selectors. Instead of

<xsl:value-of select="[@type='box'] />

which gives whats inside the tag; what can i use to get the name of the tag which contains this 'type=box' attribute ? (For. eg Usages, NonUsages, etc..)

Upvotes: 3

Views: 2969

Answers (1)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243469

This transformation is intended to only provide the necessary corrections to your original transformation:

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

    <xsl:template match="/">
        <html>
            <body>
                <h2> Test</h2>
                <xsl:for-each select="/*/*/*[@type='set']/*[@type='box']">
                    <xsl:value-of select="." />
                    <br/>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document (after correcting it to make it well-formed XML document):

<Beats>
 <Beat>
   <Personal type="set">
      <Usages type="box">
       1233
      </Usages>
      <NonUsages type="box">
       4122
      </NonUsages>
   </Personal>

   <NonPersonal type="unset">
      <Damages type="box">
       6466
      </Damages>
      <NonDamages type="box">
       5544
      </NonDamages>
   </NonPersonal>

   <Confidential type="set">
      <Discounts type="box">
       1233
      </Discounts>
      <NonDiscounts type="box">
       4122
      </NonDiscounts>
   </Confidential>
 </Beat>
</Beats>

the (what I guess is) wanted result is produced:

<html>
   <body>
      <h2> Test</h2>
       1233
      <br/>
       4122
      <br/>
       1233
      <br/>
       4122
      <br/>
   </body>
</html>

and it is displayed in the browser as:

Test

1233
4122
1233
4122


On your second question:

And one more thing i couldnt figure out was how to get the name of tags while using attributes as selectors. Instead of

<xsl:value-of select="[@type='box'] />

You want something as:

<xsl:for-each select="/*/*/*[@type='set']/*[@type='box']">
  <xsl:value-of select="name()"/>
  <xsl:text> : </xsl:text>
  <xsl:value-of select="." />
  <br/>
</xsl:for-each>

The complete transformation now becomes:

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

    <xsl:template match="/">
        <html>
            <body>
                <h2> Test</h2>
                <xsl:for-each select="/*/*/*[@type='set']/*[@type='box']">
                  <xsl:value-of select="name()"/>
                   <xsl:text> : </xsl:text>
                    <xsl:value-of select="." />
                    <br/>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

and when it is applied on the same XML document (above), the result is:

<html>
   <body>
      <h2> Test</h2>Usages : 
       1233
      <br/>NonUsages : 
       4122
      <br/>Discounts : 
       1233
      <br/>NonDiscounts : 
       4122
      <br/>
   </body>
</html>

and this is displayed by the browser as:

Test

Usages : 1233
NonUsages : 4122
Discounts : 1233
NonDiscounts : 4122

Upvotes: 4

Related Questions