View Full Version : using html elements as well in xml
Fou-Lu
11-25-2004, 11:55 AM
Hi, I'm fairly new with XML, and I have a problem with sending data through my xml, and outputting it as html, when it comes in as html in the first place. Lets see if I can create something as an example...
<root>
<area>
<title>Welcome to <span class="regularfont">my site!</span></title>
</area>
</root>
Perfect, this is a simple little example to show what I mean! See, most of my text is dynamically generated, but I cannot get it to send over elements such as spans, divs, etc. I know all that are being used, and there are four or five of them. I assume naturally that since XML will not assume that span and div etc, are elements, that I will need to state it as such. The problem is, I don't know how to drag the style/class and other properties out of them. Usually there will just be a class in it, but sometimes there may be a style.
Assumably, wrapping it in a CDATA won't really help me much, as it still won't treat it as a span (is my guess anyway.).
But how do I go abouts matching the span, and pulling the class/style out of it?
<xsl:template match="span">
<!-- This is where I should get the class, but I don't know how to extract it -->
<span class="?"><xsl:value-of select="." /></span>
</xsl:template>
Hope thats clear on what I mean ¬_¬
<xsl:template match="span">
<!-- This is where I should get the class, but I don't know how to extract it -->
<span class="{@class}"><xsl:value-of select="." /></span>
</xsl:template>
Fou-Lu
11-26-2004, 02:38 AM
Thanx jkd, thats what I was using, so I shouldn't have had any problems. However, the problem appears to exist that I cannot right both the title and the span in seperate template elements. Heres what I mean:
<xsl:template match="title">
<b><xsl:value-of select="." /></b>
</xsl:template>
<xsl:template match="span">
<span class="{@class}"><xsl:value-of select="." /></span>
</xsl:template>
I found when I deleted the template for title, it would work no problem at all. I assume that this is probably an easy fix, but when I display it will show it all as <b>Title here, with possible span</b>, instead of having the <span> in there as well. The span class is a simple font-weight:normal; to it. Now, it makes sense looking at it as to why it would say, yeah it should all be bold. And normally, I could just plug an if into the title part to add the span like that, however I won't know for certain if that will appear anywhere, and is the reason why I want to add the span to its own template match. Is there a way to tell the xml that the span has priority over the title, and if span exists to be sure to include it into the title template?
<xsl:template match="title">
<b><xsl:apply-templates match="*"/></b>
</xsl:template>
<xsl:template match="span">
<span class="{@class}"><xsl:value-of select="." /></span>
</xsl:template>
Or something like that.
Fou-Lu
11-26-2004, 03:09 AM
Yeah, it was a good thought, but it was a no go. I know its not the same as how html works, in the sense that HTML will have no problem with processing the span within bold mark up. But the only difference appears that the markup is always inherited, which I don't want it to be of course. I'll try maybe dropping the span section with the standard class, and changing the title from the <b>title</b> to <span style="font-weight:bold;">title</span>. Perhaps it will accept it that way.
Yeah, that didn't work either... hmm, any other suggestions?
mpjbrennan
11-26-2004, 08:58 AM
Hi Fou-Lu
Is this what you want?
Patrick
XML file
------------
<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/xsl" href="test_xsl.xml"?>
<root>
<area>
<title class="highlight">Welcome to
<span class="regularfont">my site!</span>
</title>
</area>
</root>
XSL File
------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<head>
<style type="text/css">
.highlight {font-weight:bold; color:blue}
.regularfont {font-weight:normal; color:red}
</style>
</head>
<body>
<xsl:apply-templates select="*" />
</body>
</html>
</xsl:template>
<xsl:template match="title">
<p class="title">
<xsl:apply-templates />
</p>
</xsl:template>
<xsl:template match="span">
<span class="{@class}">
<xsl:value-of select="." />
</span>
</xsl:template>
</xsl:stylesheet>
Fou-Lu
11-26-2004, 09:41 AM
Yes, I haven't tried it but it looks very much like what I need. The only difference being, for my title it will be within <b></b> instead. Its just odd because it wouldn't allow the markup to work correctly with it, so I figured it was more of an HTML markup. This is essentially what I need:
<b>Welcome to <i>My Site!</i></b>
Which I've never had a problem with in HTML before. But when I went to the XML aspect, I found it would override and add bold to both. Not quite what I'm doing with it, but similar and easier principle. So, I want the above code to apear as:
Welcome to My Site
for instance.
All I was looking for was more or less why it wouldn't work, and I knew it had something to do with how I set it up. I could have easily done something like just add an if into the title template, to process the span if found. But I wanted to avoid doing that mearly because it could appear elsewhere as well.
I'll give it a shot here, and see how it works!
It works great! Thanx a lot guys!
If you don't mind me asking, why is it that the title has apply-template to it, while the span has value-of only?
<xsl:template match="title">
<p class="title">
<xsl:apply-templates />
</p>
</xsl:template>
Perhaps I'm just confused by how the apply-templates work correctly...
mpjbrennan
11-26-2004, 10:16 AM
If you don't mind me asking, why is it that the title has apply-template to it, while the span has value-of only?
This is because the span is enclosed within the title tag.
BTW I posted an error in this part of the code; it should read
<xsl:template match="title">
<p class="{@class}">
<xsl:apply-templates />
</p>
</xsl:template>
Patrick
PS Generally it isn't good practice to use html tag names for XML elements as it can lead to confusion when debugging complex XSL stylesheets.
Fou-Lu
11-26-2004, 11:33 AM
Yeah, normally I don't use html as tags in my xml, though I often use the title tag. I suppose that probably could cause problems all in itself. The only problem is that some of my information has it hardcoded with the html, though only be in spans, dfn and p tags. I figure those will be fine as long as I keep track of them yeah?
OH, and why we're on a little bit about template application, is my understanding what you mentioned along the lines of it will only process the templates within it?
Since you said that the span is within the title, using the apply templates will only apply templates that are children? So, by using apply-templates within the template match for title, it also applies the span templates.
One part that confuses me still, why is it that when you use template match for title, there is no value-of for it required? Is it because it somehow relates back to itself?
XML will be more complicated than I thought ¬_¬
mpjbrennan
11-26-2004, 02:19 PM
Because the span element is within the title element the the context node remains the title - so the call to <xsl:value-of select="." /> sweeps everything up. You can if you wish select the two portions of text separately as follows:
XSL file
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<head>
<style type="text/css">
.highlight {font-weight:bold; color:blue}
.regularfont {font-weight:normal; color:red}
</style>
</head>
<body>
<xsl:apply-templates select="*" />
</body>
</html>
</xsl:template>
<xsl:template match="title">
<p class="{@class}">
<xsl:value-of select="text()" />
<xsl:apply-templates select="span" />
</p>
</xsl:template>
<xsl:template match="span">
<span class="{@class}">
<xsl:value-of select="text()" />
</span>
</xsl:template>
</xsl:stylesheet>
It puts extra lines in but I guess it probably makes it more clear what is going on.
Patrick
Fou-Lu
11-26-2004, 04:35 PM
Yes, I thought that was how it worked.
Excellent. That was great, thanx a lot! As with the select="text()" I'm assuming that the text is simply whats between the elements as text correct. Obviously the tutorials I have read are... not overly great. Do you have an xml/xslt - xslfo tutorial that you would recommend I check out?
mpjbrennan
11-26-2004, 05:51 PM
<xsl:value-of select="." /> is shorthand for <xsl:value-of select="node()" />.
<xsl:value-of select="text()" /> selects only the text attached to the node.
I can't recommend a tutorial - all the ones I have seen are fairly superficial. If you want to really get into XSLT then I would recommend Michael Kay's book entitled "XSLT - Programmer's Reference" (ISBN 1-861005-06-7) - currently available on Amazon at $23
patrick
Fou-Lu
11-27-2004, 02:03 AM
Hey, thanks a lot! May be a worthwhile one to check out!
Fou-Lu
12-02-2004, 05:21 AM
Ok, um, I did some alterations and I'm having some problems with this again :rolleyes:
Heres some xml example code, I have this dynamically generated, so that there can be any number of area containing any number of row.
...
<area>
<title>Options</title>
<row type="radio" alt="alt1">
<name>Show Email<dfn>(Select to allow others to view your email. If set as no, they will be directed to an email form instead.)</dfn></name>
<fieldname>showemail</fieldname>
<value>0</value>
</row> <row type="radio" alt="alt2">
<name>Allow others to view your biography</name>
<fieldname>showbiography</fieldname>
<value>1</value>
</row>
...
Most of its straight forward, this will create a table with a header "Options" followed by two alternating colored rows containing radio buttons for form validations. This is fine, I have it all set, and will show the xsl below, but I'm having some problems with the xsl again, and don't quite know how to alter it to show correctly (again, lol). In any case, here it is:
...
<xsl:template match="root">
<html>
<head>
<title><xsl:value-of select="pagetitle" /></title>
</head>
<body style="margin:0px;">
<div class="pagetitle"><xsl:value-of select="pagetitle" /></div>
<div style="margin:20px; text-align:center;">
<form method="post">
<input type="hidden" name="do" value="dotest" />
<xsl:apply-templates select="area" />
<input type="submit" value="Submit Me!" />
</form>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="area" name="area">
<div class="tborder" style="text-align:left;">
<xsl:apply-templates />
<div class="tablecontentborder">
<xsl:apply-templates select="rows" />
</div>
</div>
</xsl:template>
<xsl:template match="title" name="header">
<div class="tabletopborder">
<div class="tcat">
<b><xsl:apply-templates /></b>
</div>
</div>
</xsl:template>
<xsl:template match="span" name="span">
<span class="{@class}" style="{@style}"><xsl:value-of select="." /></span>
</xsl:template>
<xsl:template match="row">
<div class="{@alt}">
<div class="spacer"></div>
<xsl:if test="@type=\'radio\'">
<xsl:call-template name="radio">
<xsl:with-param name="rowname" select="name" />
<xsl:with-param name="field" select="fieldname" />
<xsl:with-param name="selectvalue" select="value" />
</xsl:call-template>
</xsl:if>
<div class="spacer"></div>
</div>
</xsl:template>
<xsl:template name="radio">
<xsl:param name="rowname" select="\'Currently N/A\'" />
<xsl:param name="field" select="\'\'" />
<xsl:param name="selectvalue" select="\'0\'" />
<div class="leftcell">
<xsl:apply-templates />
</div>
<div class="rightcell">
<xsl:element name="input">
<xsl:attribute name="type">radio</xsl:attribute>
<xsl:attribute name="name"><xsl:value-of select="$field" /></xsl:attribute>
<xsl:if test="$selectvalue=\'1\'">
<xsl:attribute name="checked"> Checked</xsl:attribute>
</xsl:if>
<xsl:attribute name="value">1</xsl:attribute>
</xsl:element>
<xsl:text>Yes </xsl:text>
<xsl:element name="input">
<xsl:attribute name="type">radio</xsl:attribute>
<xsl:attribute name="name"><xsl:value-of select="$field" /></xsl:attribute>
<xsl:if test="$selectvalue!=\'1\'">
<xsl:attribute name="checked"> Checked</xsl:attribute>
</xsl:if>
<xsl:attribute name="value">0</xsl:attribute>
</xsl:element>
<xsl:text>No </xsl:text>
</div>
</xsl:template>
<xsl:template match="dfn" name="dfn">
<dfn>
<xsl:value-of select="." />
</dfn>
</xsl:template>
...
Now, this is fairly short and sweet, pretty much straight forward as well. This works pretty much fine, however below the dfn section, it displays the elements as well below them, so it looks kind of like this:
Show Email
(Select to allow others to view your email. If set as no, they will be directed to an email form instead.)</name>
showemail0
I guess my question is, why is it doing this? Is it because of how I have placed the template applications within the area element? Or... perhaps different? Any help would be great!
mpjbrennan
12-02-2004, 10:28 AM
It's because you haven't written templates for the <fieldname> and <value> elements. Your browser defaults to displaying their textual content. To make them disappear write templates for them which do nothing, eg;
<xsl:template match="fieldname" />
<xsl:template match="value" />
Patrick
Fou-Lu
12-02-2004, 10:41 AM
Ah I see. Simple fix then ;)
I assume than that this is the standard for xml/xsl to react to this, or is there a way to get around this, using doctype or anything else of the sorts? Just incase I overlook something, I don't want something to horribly display itself in my browser.
mpjbrennan
12-02-2004, 06:03 PM
I think this is standard behaviour. I check all my pages in Internet Explorer 6.0 (68% of users) and Firefox 1.0 (20% of users use this or Mozilla which behaves the same). IE5 (5%) does not support this version of XSLT and Opera 7 (2%) does not support client-side XSLT at all
patrick
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.