I am attempting to write an XSLT for an XML file I have and I am getting no results.
A simple example of my XML:
<Monsters>
<Monster>
<Name>Dracula</Name>
<Actor>Bela Lugosi</Actor>
</Monster>
</Monsters>
And a simple XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<head>
</head>
<body style="background: #FFFFCC">
<xsl:for-each select="Monsters/Monster">
<xsl:value-of select="Name" />
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl>
The resulting display is entirely empty and I just know it's something silly that I'm missing.
You don't have a proper closing tag for xsl:stylesheet element.
Related
I'm getting this error when trying to convert a XML document with XSL. I've only just started coding with XML, so I am sure I am missing something simple, but cant seem to find much information about it online.
Booklist.XML
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="booklist.xsl"?>
<CATALOG>
<BOOK>
<NAME>
<TITLE>Caring for Sheep</TITLE>
</NAME>
<PAGES> 60 </PAGES>
<PRICE>$34.99</PRICE>
</BOOK>
</CATALOG>
And my XSL File:
Booklist.XSL
<?xml version="1.0"?>
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="CATALOG/BOOK/NAME">
<div style="background-color:teal;color:white;padding:4px">
<xsl:value-of select="name">;
</div>
</xsl:for-each>
<xsl:for-each select="CATALOG/BOOK">
<div style="background-color:teal;color:white;padding:4px">
</div>
</xsl:for-each>
</body>
Can anyone see an error here?
You're sort of mixing the Literal Result Element as Stylesheet simplified syntax with the regular syntax by putting a literal result element <body> outside any template, yet not at the top level. If you want to use this simplified syntax, get rid of the <xsl:stylesheet> and <xsl:output> elements, so that <body> is at the top level.
Also, XML and XPath are case-sensitive with regard to element names, so you'll need to fix the inconsistency between e.g. "catalog" and <CATALOG>.
Well, if the for some reasons which are hard to figure out the simplified syntax doesn't work for you I would suggest using the "normal coding", which would be something like this in your case:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:template match="/">
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="/CATALOG/BOOK/NAME">
<div style="background-color:teal;color:white;padding:4px">
<xsl:value-of select="name"/>
</div>
</xsl:for-each>
<xsl:for-each select="/CATALOG/BOOK">
<div style="background-color:teal;color:white;padding:4px">
</div>
</xsl:for-each>
</body>
</xsl:template>
</xsl:stylesheet>
I have to display an XML document using XSLT but I would like apply the <p> and <i> HTML tags from the original XML document. For example p tag from XML would create a new paragraph. What would be the best way to accomplish this?
XML and XSLT code posted below.
Edit: clarified the original question
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="tour.xsl"?>
<cars>
<car>
<description>
<p><i>There is some text here</i> There is some more text here</p>
<p>This should be another paragraph</p>
<p>This is yet another paragraph</p>
</description>
</car>
</cars>
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0"/>
<xsl:template match="/">
<html>
<head>
<title>Title</title>
</head>
<body>
<xsl:value-of select="car"/><p/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>`
your actual question can be answered with a stylesheet like this, which uses apply-templates
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>Title</title>
</head>
<body>
<xsl:apply-templates select="/cars/car/description/*"/>
<p/>
</body>
</html>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
However, if you have multiple cars you probably want to have some headlines. Then a stylesheet like this may point towards that goal:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>Title</title>
</head>
<body>
<xsl:apply-templates select="/cars/car/*"/>
<p/>
</body>
</html>
</xsl:template>
<xsl:template match="description">
<h1>Subtitle</h1>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
You can extend your template to copy over the p elements like this:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0"/>
<xsl:template match="/">
<html>
<head>
<title>Title</title>
</head>
<body>
<xsl:for-each select="/cars/car">
<xsl:for-each select="description/p">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Given your XML input, the above XSLT will produce this output:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Title</title>
</head>
<body>
<p><i>There is some text here</i> There is some more text here
</p>
<p>This should be another paragraph</p>
<p>This is yet another paragraph</p>
</body>
</html>
Update:
I am trying to run in komodo's built in browser and ie.
You'd have to research komodo's XSLT capabilities. Also, be aware of challenges running XSLT in the browser; better to run on the server or in batch mode and only use the browser to display the results.
That said, the following XML file will open in IE 11 and be styled per the above XSLT sheet (named tour.xml and located in the same directory as the XML file):
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type='text/xsl' href='tour.xsl'?>
<cars>
<car>
<description>
<p><i>There is some text here</i> There is some more text here</p>
<p>This should be another paragraph</p>
<p>This is yet another paragraph</p>
</description>
</car>
</cars>
Here's a screenshot of the output in IE 11:
Update 2
I tried the template solution but it still returns unformatted text in
one line.
If IE 11 is given an XML file without a xml-stylesheet PI,
<?xml-stylesheet type='text/xsl' href='tour.xsl'?>
then it will display the XML in an outline form.
If IE 11 is given an XML file with a xml-stylesheet PI and it can find the XSLT file specified, it will apply the XSLT and display the results in the browser. This result can be seen in the above screenshot (and is your desired result).
If IE 11 is given an XML file with a xml-stylesheet PI and it cannot find the XSLT file specified, it will display unformatted text in one line as you describe.
Therefore, focus the search for your problem on the location and name of the XSLT file. Here is what happens when I intentionally force such behavior by renaming the XSLT file,
<?xml-stylesheet type='text/xsl' href='tour_CANNOT_FIND.xsl'?>
so that it cannot be found:
Note: Press F-12 to reveal the console.
Then, if you click on the "Allow blocked content" button:
You see the diagnostic message that tour_CANNOT_FIND.xsl cannot be found. If you resolve the problem of IE not finding your XSLT file, you should then see the formatted results of your XSLT file in the browser.
Hello all I wnt to replace some xml node tags to html tags
Example: <emphasis role="bold">Diff.</emphasis>
i want to convert it to <b>Diff.</b>
Example: <emphasis role="italic">Diff.</emphasis>
i want to convert it to <i>Diff.</i>
Any ideas?
As this answer suggests, XSLT is the de-facto standard to process XML from one format to another.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="//emphasis[#role='bold']">
<b><xsl:apply-templates select="node()" /></b>
</xsl:template>
<xsl:template match="//emphasis[#role='italic']">
<i><xsl:apply-templates select="node()" /></i>
</xsl:template>
</xsl:stylesheet>
XSLT makes use of XPath queries to query and process the content. For instance //emphasis[#role='bold'] matches any tag (no matter how deep) that has an attribute role with value 'bold', within such blocks, you specify how to process it. By presenting it within <b>...</b> blocks, XSLT will present the output within these blocks as well. And select="node()" inserts the content of the node there.
Example: say the above code is stored in process.xslt, you can process this using xsltproc (or another XSLT processor):
xsltproc process.xslt testinput.xml
If testinput is:
<?xml version="1.0"?>
<test>
<emphasis role="italic"><foo>Diff<emphasis role="italic">bar</emphasis></foo>.</emphasis>
<emphasis role="bold">Diff.</emphasis>
</test>
the resulting output is:
$ xsltproc process.xslt testinput.xml
<?xml version="1.0" encoding="ISO-8859-15"?>
<test>
<i><foo>Diff<i>bar</i></foo>.</i>
<b>Diff.</b>
</test>
To output it as HTML, you can override the main of the XSLT by including
<xsl:template match="/">
<html>
<head>
<title>Some title</title>
</head>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
in the <xsl:stylesheet>. In that case, the output is:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-15">
<title>Some title</title>
</head>
<body><test>
<i><foo>Diff<i>bar</i></foo>.</i>
<b>Diff.</b>
</test></body>
</html>
I am trying to use the tokenize function in XSLT and it is not working
<xsl:variable name="stringList" select="tokenize('XPath,is,fun', ',')"/>
<xsl:for-each select="$stringList">
<xsl:value-of select="." />
</xsl:for-each>
Is this anything wrong in this ? I tried this both in eclipse and in the w3schools tutorial editor
Actual code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:rg="http://www....."
xmlns="http://wwww.w3.org/1999/xhtml" >
<xsl:template match="/">
<html>
<head>
<title>Temp</title>
</head>
<body>
<xsl:variable name="stringList" select="tokenize('XPath,is,fun', ',')" />
<xsl:for-each select="$stringList">
<xsl:value-of select="." /><br/>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Tokenize is actually an XSLT 2.0 function, and so you will need to use an XSLT processor that supports XSLT 1.0. The editor at W3Schools is XSLT 1.0 only.
I tried your XSLT at http://xslttest.appspot.com/ as an example, and it works happily.
I just want to confirm whether we can insert html tags inside the xsl variable?
example
<xsl:variable name="htmlContent">
<html>
<body>
hiiii
</body>
</html>
</xsl:variable>
if i use
<xsl:value-of select="$htmlContent"/>
I shoud get
<html>
<body>
hiiii
</body>
</html>
Is it possible? i have tried
<xsl:value-of disable-output-escaping="yes" select="$htmlContent"/>
Eventhough i am not getting the desired output
Do not use value-of, which gets the text value of the selected node. Instead use copy-of, which copies the entire tree (nodes and all) into the output:
<xsl:copy-of select="$htmlContent"/>
Here is a full example:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:variable name="htmlContent">
<html><body>hiiii</body></html>
</xsl:variable>
<xsl:template match="/">
<xsl:element name="htmlText">
<xsl:copy-of select="$htmlContent"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
This will always produce the xml:
<htmlText>
<html>
<body>hiiii</body>
</html>
</htmlText>