Click to See Complete Forum and Search --> : Problems using apply-templates to transform xml file - newbie


Pip1
01-11-2009, 09:15 AM
I am a newbie at XML and really need some help.

I'm having problems trying to create an XSLT style sheet to transform the xml file 'scene3.xml' (relevant code below):-

<?xml version="1.0" ?>
<?xml-stylesheet type="text/xsl" href="scene3toXHTML.xsl"?>
<PLAY>
<TITLE>The Tragedy of Macbeth</TITLE>
<ACT>
<TITLE>ACT I</TITLE>
<CHARACTERS>
<GROUP DESCRIPTION="Generals">
<PERSON>MACBETH</PERSON>
<PERSON>BANQUO</PERSON>
</GROUP>
<GROUP DESCRIPTION="Noblemen">
<PERSON>ROSS</PERSON>
<PERSON>ANGUS</PERSON>
</GROUP>
<GROUP DESCRIPTION="Witches">
<PERSON>FIRST WITCH</PERSON>
<PERSON>SECOND WITCH</PERSON>
<PERSON>THIRD WITCH</PERSON>
</GROUP>
</CHARACTERS>
<SCENE>
<TITLE>SCENE III. A heath near Forres.</TITLE>
<STAGEDIR>Thunder. Enter the three Witches</STAGEDIR>



The first portion of the desired output should look like the screenshot in the attached 'file1.png'. So far, I have managed to code the first 4 lines of code correctly, starting with 'The Tragedy of Macbeth, ACT 1, SCENE 111 A heath near Forres and Characters. After that, I can't get the list of characters to appear on separate lines. Also, I can get the 1st 'GROUP DESCRIPTION' title to appear, but the remaining two 'GROUP DESCRIPTION's don't appear at all.
See XSLT code below:-

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

<xsl:output method="xml" encoding="ISO-8859-1"
version="1.0" omit-xml-declaration="yes"
media-type="text/html" indent="yes" />

<xsl:template match="/">

<html>
<head>
<title>A Simple XSLT style sheet</title>
<meta http-equiv="content-type"
content="text/html; charset=iso-8859-1" />
<link href="macbeth.css" rel="stylesheet" type="text/css" />
</head>
<body>
<xsl:for-each select="PLAY">

<dl>
<dt><xsl:apply-templates select="TITLE"/></dt>
<p></p>
<dt><xsl:apply-templates select="ACT"/></dt>
<p></p>
<dd><xsl:apply-templates select="ACT/SCENE"/></dd>
<p></p>
<hr />
<p></p>
<h3>Characters</h3><br />
<dd><xsl:apply-templates select="ACT/CHARACTERS"/></dd>
</dl>
<dl>
</dl>

</xsl:for-each>


</body>
</html>

</xsl:template>

<xsl:template match="TITLE">
<xsl:value-of select="."/>
</xsl:template>

<xsl:template match="ACT">
<xsl:value-of select="TITLE"/>
</xsl:template>

<xsl:template match="ACT/SCENE">
<xsl:value-of select="TITLE"/>
</xsl:template>

<xsl:template match="ACT/CHARACTERS">
<xsl:value-of select="GROUP/@DESCRIPTION"/>
<xsl:value-of select="."/>
</xsl:template>

</xsl:stylesheet>

I would be very grateful for any help.
Thanks.

Pip1
01-13-2009, 11:21 AM
I,ve managed to get a bit further. For example, a section of the output looks as below:-

Generals

Macbeth Banquo

What I want it to look like is:


Generals

Macbeth
Banquo

So, how do I get the line-space between Macbeth and Banquo. Below is my code and the relevant bit from where it starts is:-

<dd><xsl:apply-templates select="ACT/CHARACTERS/GROUP"/></dd>


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

<xsl:output method="xml" encoding="ISO-8859-1"
version="1.0" omit-xml-declaration="yes"
media-type="text/html" indent="yes" />

<xsl:template match="/">

<html>
<head>
<title>A Simple XSLT style sheet</title>
<meta http-equiv="content-type"
content="text/html; charset=iso-8859-1" />
<link href="macbeth.css" rel="stylesheet" type="text/css" />
</head>
<body>
<xsl:for-each select="PLAY">

<dl>
<dt><xsl:apply-templates select="TITLE"/></dt>
<p></p>
<dt><xsl:apply-templates select="ACT/TITLE"/></dt>
<p></p>
<dd><xsl:apply-templates select="ACT/SCENE/TITLE"/></dd>
<p></p>
<hr />
<p></p>
<h3>Characters</h3><br />
<dd><xsl:apply-templates select="ACT/CHARACTERS/GROUP"/></dd>

</dl>
</xsl:for-each>


</body>
</html>

</xsl:template>

<xsl:template match="TITLE">
<xsl:value-of select="."/>
</xsl:template>

<xsl:template match="ACT/TITLE">
<xsl:value-of select="."/>
</xsl:template>

<xsl:template match="ACT/SCENE/TITLE">
<xsl:value-of select="."/>
</xsl:template>

<xsl:template match="ACT/CHARACTERS/GROUP">
<p><xsl:value-of select="@DESCRIPTION"/></p>
<p><xsl:value-of select="."/></p>
<br />
</xsl:template>

</xsl:stylesheet>

Thanks

jkmyoung
01-13-2009, 04:05 PM
Use apply-templates within apply-templates probably.
I'm not sure why you're not associating everything with characters that belongs to characters. eg. like:
<dd><xsl:apply-templates select="ACT/SCENE"/></dd>
<p></p>
<hr />
<p></p>
<xsl:apply-templates select="ACT/CHARACTERS"/>
</dl>
...
<xsl:template match="CHARACTERS">
<h3>Characters</h3><br />
<dd>
<xsl:apply-templates/>
</dd>
</xsl:template>

<xsl:template match="GROUP">
<p><xsl:value-of select="@DESCRIPTION"/></p>
<br />
<xsl:apply-templates/>
<br/>
</xsl:template>
<xsl:template match="PERSON">
<p><xsl:value-of select="."/></p>
</xsl:template>

Pip1
01-13-2009, 06:07 PM
Thanks very much. I also have no idea as to why I didn't use 'template match = "PERSON" I'm learning a lot!

Thanks again!