slawek
slawek

Reputation: 13

XSL - transforming XML elements to HTML depending on their properties

Maybe somebody had similar problem. I need to transform using XSL the input XML file:

<decision>
    <akapit nr = 1>
           This is <b>important</b> decision for the query number <i>0123456</i>
    </akapit>
</decision>

As output I need a html document which displays text within elements <b></b> as bolded, elements in <i></i> as italic...etc. So, basically I need to format output HTML from XML element named <akapit> depending on their subelements' names. Any idea how to use XSL template in such a case?

Upvotes: 1

Views: 177

Answers (3)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243579

In case the markup elements names aren't the same as the corresponding Html element names, for example:

<decision>
    <akapit nr="1">
    This is 
        <bold>important</bold> decision for the query number
        <italic>0123456</italic>
    </akapit>
</decision>

Then a very simple application of the identity rule is this:

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

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

 <xsl:template match="akapit">
  <div><xsl:apply-templates/></div>
 </xsl:template>

 <xsl:template match="bold"><b><xsl:apply-templates/></b></xsl:template>
 <xsl:template match="italic"><i><xsl:apply-templates/></i></xsl:template>

 <xsl:template match="/*"><xsl:apply-templates/></xsl:template>
</xsl:stylesheet>

And when this transformation is applied on the above XML document, the wanted, correct result is produced:

<div>
    This is 
        <b>important</b> decision for the query number
        <i>0123456</i>
</div>

Do Note: Using xsl:apply-templates should be preferred to xsl:copy-of as the latter doesn't allow flexibility to further process the selected nodes -- it only copies them.

Upvotes: 1

StuartLC
StuartLC

Reputation: 107367

If I understand you correctly, you can just use copy-of to duplicate everything under your akapit element.

<xsl:template match="/decision/akapit[@nr='1']">
    <xsl:copy-of select="child::node()"/>
</xsl:template>

Upvotes: 0

Martin Honnen
Martin Honnen

Reputation: 167716

The basic approach to such problems is

<xsl:template match="akapit">
  <div>
   <xsl:copy-of select="node()"/>
  </div>
</xsl:template>

That should suffice as long as the XML input uses the same elements for e.g. bold or italic as HTML uses.

If you have other elements in the input XML e.g.

<decision>
    <akapit nr = 1>
           This is <bold>important</bold> decision for the query number <i>0123456</i>
    </akapit>
</decision>

then you need to transform stuff e.g.

<xsl:template match="akapit">
  <div>
    <xsl:apply-templates/>
  </div>
</xsl:template>

<xsl:template match="akapit//*">
  <xsl:copy>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<xsl:template match="akapit//bold">
  <b>
    <xsl:apply-templates/>
  </b>
</xsl:template>

Upvotes: 2

Related Questions