[web] Need some help with XSLT

Started by
8 comments, last by jedifreeman 18 years, 8 months ago
I'm attempting to use XML/XSLT to do some work, and as a precursor to do that I'm trying to take fairly simple XML which is more or less identical to HTML, and get the right results. Here's my XML doc:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<?xml-stylesheet type="text/xsl" href="default.xsl" ?>

<doc>
	<i><b>Test</b></i>
	<b><i>Test</i></b>
</doc>
The idea is that I should get correctly formatted HTML output from the XSL transform that I do. However, I can't get it to work. I'm trying something like this:

<xsl:template match="/">
	<html>
		<body>
			<xsl:apply-templates select="*" />
		</body>
	</html>
</xsl:template>

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

<xsl:template match="i">
	<i><xsl:value-of select="." /></i>
</xsl:template>
But I just get an italic Test followed by a bold Test, not two bold-italic Tests. I can't get the inner tag to ever match properly. I think this is mainly a question of getting my apply-templates line right, but I'm not quite sure. I'd really appreciate some help.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Advertisement
Also, if I use select="doc//*", I just get italic test, bold test, bold test, italic test.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
I was able to get it to work by making a few changes:

Here is the xml file

<?xml version="1.0" encoding="ISO-8859-1" ?><?xml:stylesheet type="text/xsl" href="default.xsl" ?><doc>	<one>		<b>Test</b>	</one>	<two>		<i>Test</i>	</two></doc>


Here is the 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:template match="/">	<html>		<body>			<xsl:apply-templates select="*" />		</body>	</html>  </xsl:template>  <xsl:template match="one">	<b><xsl:value-of select="b" /></b>  </xsl:template>  <xsl:template match="two">	<i><xsl:value-of select="i" /></i>  </xsl:template></xsl:stylesheet>


This prints out a bold Test, and an italic test. In a HTML format. The major change I made, was adding the xsl:stylesheet, and xmlns:xsl declaration. I also changed the i and b nodes to, one and two....because I am easily confused. : )
You completely missed the point. The correct output is:
TestTest
Furthermore, the XSLT has to be able to deal with any arbitrary nesting of elements. The point is that you can't change the XML file. The XML file can be nested anyway the author wants. And these kinds of strange circular nestings are to be expected. That's why this is so damn touchy.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Well, I am no expert in XML. I am only trying to help.

Would something like this work for what you are trying to do?
<xsl:template match="b|i">	<i><b><xsl:value-of select="." /></b></i></xsl:template>


Keeping your original XML file this seems to work. The output is TestTest.

I know you are trying to access the nested tags, but I am not certain how to do that. What I am seeing is that the template is being applied to the outer tag only, and ignores the nested tag.

Very sorry if this is no help at all.
Sorry if I seemed annoyed. I'm just a bit frustrated, since I can't seem to find anybody who has a clue about how to do this. (And unfortunately your latest attempt doesn't really deal with things right either.)

The problem is that I'm trying to basically replicate HTML in the XML document, and doing so is turning out to be quite difficult. There are a lot of strange cases which are difficult to deal with. My relative lack of knowledge about XSLT isn't helping either. I find it difficult to believe this isn't possible, but anything I try falls over on my test cases. This simply happens to be a relatively difficult but simple one. I can set up all kinds of jacked up nesting, and I need to be able to transform all of it into equivalent HTML. If somebody wants to write <u><i><b>Test</b></i></u>, then I need to parse that correctly as well.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
Learn how to use the copy-of and copy elements to copy elements into the result tree. They will allow you deal with nested elements. copy copies the current node to the result, and copy-of copies the fragment given by select attribute. Read the specification for details and example usage.

Using your example:
<xsl:template match="b">  <xsl:copy>    <xsl:apply-templates/>  </xsl:copy></xsl:template>


Also, keep in mind that if you are sending the result as XHTML, you need to use the XHTML namespace. Otherwise the document won't be rendered as such.
Free Mac Mini (I know, I'm a tool)
I don't understand what xsl:apply-templates does when it's not given a select parameter. And some further experimentation leads me to believe that that's the key to making this work; that is, this is equivalent to the copy:
<xsl:template match="b">    <b><xsl:apply-templates/></b></xsl:template>

So, what does that blank apply-templates do, exactly?
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
An empty apply-templates just traverses the subtree copying text nodes until it encounters a node that matches another template.
Free Mac Mini (I know, I'm a tool)
Here, this should work... your XML file is unchanged...

<?xml version="1.0"?><?xml-stylesheet type="text/xsl" href="default.xsl" ?><doc>	<i><b>Test</b></i>	<b><i>Test</i></b></doc>


and your XSLT file should look like this:

<xsl:stylesheet version="1.0"    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"    xmlns="http://www.w3.org/TR/xhtml1/strict">                <xsl:template match="/">    <html>        <body>            <xsl:apply-templates select="*" />        </body>    </html></xsl:template><xsl:template match="b">    <b><xsl:apply-templates /></b></xsl:template><xsl:template match="i">    <i><xsl:apply-templates /></i></xsl:template><xsl:template match="text()">    <xsl:value-of select="." /></xsl:template></xsl:stylesheet>

This topic is closed to new replies.

Advertisement