I have made an application that creates an xsl and xml file, but the output is not shown as XML layout (like an expected HTML table).
What changes should be made in either the xml or xsl file to make the output look like a HTML table?
I checked various browsers but all show either the output below (Edge) or no output at all.
The xml file (newfile_output.xml) has content:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl"
href="C:\Users\Michel\Documents\newfile_output.xsl"?>
<patch_list xml:lang="en">
<patch>
<type>Program</type>
<id>I-B000</id>
<name>Jazz Dry/Amb1 Kit SL1,2</name>
<favorite> </favorite>
<category>Drums</category>
<subcategory>Natural Drums</subcategory>
<setlistname></setlistname>
<setlistslotreferenceid></setlistslotreferenceid>
<setlistslotreferencename></setlistslotreferencename>
<description></description>
</patch>
....
<patch>
<type>WaveSequence</type>
<id>U-F012</id>
<name>Looped Cello G Vibrato</name>
<favorite> </favorite>
<category></category>
<subcategory></subcategory>
<setlistname></setlistname>
<setlistslotreferenceid></setlistslotreferenceid>
<setlistslotreferencename></setlistslotreferencename>
<description></description>
</patch>
</patch_list>
The xsl file (newfile_output.xsl) has the following content:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>Patch List</h2>
<table border="1">
<tr bgcolor="#80a0ff">
<th>ListSubType</th>
<th>Id</th>
<th>Name</th>
<th>Fav</th>
<th>Category</th>
<th>Sub Category</th>
<th>Set List Slot Reference Id</th>
<th>Set List Slot Reference Name</th>
<th>Set List Name</th>
<th>Description</th>
</tr>
<xsl:for-each select="patch_list/patch">
<tr>
<td><xsl:value-of select="type"/></td>
<td><xsl:value-of select="id"/></td>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="favorite"/></td>
<td><xsl:value-of select="category"/></td>
<td><xsl:value-of select="subcategory"/></td>
<td><xsl:value-of select="setlistslotreferenceid"/></td>
<td><xsl:value-of select="setlistslotreferencename"/></td>
<td><xsl:value-of select="setlistname"/></td>
<td><xsl:value-of select="description"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The output looks like:
Program I-A000 KRONOS German Grand Keyboard A.Piano Program I-A001 German
Dark Grand Keyboard A.Piano Program I-A002 R.Ferrante German Grand Keyboard
A.Piano Program I-A003 German New Age Grand Keyboard A.Piano Program I-A004
L.Mays German Grand Keyboard A.Piano Program I-A005 German Grand + VPM
Keyboard A.Piano Program I-A006 KRONOS Japanese Grand Keyboard A.Piano
Program I-A007 Japanese ...
I have tried with my IE browser it's working fine.
Check File permission and directory path of the referenced XSL file
Add
<xsl:output method="html" indent="yes" />
after your
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
element. It should look like
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
...
Related
I am facing issues while displaying the xml in html table using xsl.
1. The html view is repeating with the below xsl and
2. unable to differentiate sub elements with the same name (Eg: name tag in the below xml).
The xml is having different kinds of information in different nodes as follows.
<employee>
<address>
<street>street1</street>
<city>city1</city>
<pincode>123456</pincode>
</address>
<personalinfo>
<name>testname1</name>
<phone>999999999</phone>
<dob>23-09-34</dob>
</personalinfo>
<remarks>
<education>
<name>testname2</name>
<college>college1</college>
<gpa>7.5</gpa>
</education>
</remarks>
</employee>
and Here is my xsl
<?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"/>
<xsl:template match="employee">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="address|personalinfo|remarks">
<table width="630">
<tr>
<td>Name</td>
<td>College</td>
<td>City</td>
</tr>
<tr>
<td><xsl:value-of select="//name"/></td>
<td><xsl:value-of select="//college"/></td>
<td><xsl:value-of select="//city"/></td>
</tr>
</table>
<span><br/>
</span>
</xsl:template>
</xsl:stylesheet>
Please help me in this regard. Thank you.
Judging from your table structure, you want to move the table header up to the template matching the root node, and then get the corresponding detail of each employee using a relative (and explicit) path:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="/">
<html>
<body>
<table>
<tr>
<th>Name</th>
<th>College</th>
<th>City</th>
</tr>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="employee">
<tr>
<td>
<xsl:value-of select="personalinfo/name"/>
</td>
<td>
<xsl:value-of select="remarks/education/college"/>
</td>
<td>
<xsl:value-of select="address/city"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
The expression //name selects all the name elements anywhere in the document. That's not you want: you want the name element within the personalInfo or remarks that you are currently processing: that's select="name" for an immediate child, or select=".//name" for a descendant at any depth.
It seems odd to use the same template rule to process three elements (address|personalinfo|remarks) that have very different structure.
Basically I want images to be shown in my table if I have image links in my xml. I know I'm supposed to use attribute but whatever I tried, nothing worked.
XML
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="catalog.xsl"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<picture url="https://www.planwallpaper.com/static/images/Winter-Tiger-Wild-Cat-Images.jpg" />
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<picture url="http://i.istockimg.com/cms/resources/images/HomePage/Tiles/US_March2016/SilenceAndNoise_Signature_78262195.jpg" />
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</catalog>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
So I want instead of my links, the actual images to be shown. How would I do that? As far as I got, I get X's instead of the actual images for some reason. Any ideas why?
I tried Tim C's code and it slightly works. In his link it works but when I run it on my pc, it doesn't show the images anymore
I checked it on every browser, both windows and linux and same problem. No images appear using Tim's code. I even uploaded it on a server and the problem persists. The photos look like they are corupted or something. Any ideas?
You use the img tag in HTML, with the src attribute to show an attribute, so if you were in a template that matched picture you would do it like this
<xsl:template match="picture">
<img src="{#url}" />
</xsl:template>
The curly braces are known as "Attribute Value Templates". The expression inside the curly braces is evaluated to produce a value.
Try this XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
<th>Image</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
<td>
<xsl:apply-templates select="picture" />
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="picture">
<img src="{#url}" />
</xsl:template>
</xsl:stylesheet>
Note that if the input XML had multiple pictures for a cd, this would should all of them. To show just the first picture in this case, do <xsl:apply-templates select="picture[1]" />
Also note it might be preferred to specify a height and width for your images too, although you would need to amend the XML for that, but you add the attributes to the image in the same was as the url.
<xsl:template match="picture">
<img src="{#url}" height="{#height}px" width="{#width}px" />
</xsl:template>
I apologize for this somewhat as there are similar questions around, however I've attempted to apply all of those and cannot get mine to work with existing stylesheet html output.
I have an existing XML and an existing XSLT which has HTML markup.
I Simply want use the XSLT to also add an attribute to my XML root node but still also output the XSLT HTML.
How would I do this?
My XML: (I want to add an xmlns attribute to the node: "StockList")
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="do_it.xsl"?>
<StockList>
<StockItem>
<Item>AX123</Item>
<Description>Firetruck</Description>
<Count>500</Count>
<Order>No</Order>
</StockItem>
</StockList>
My XSLT: (do_it.xsl)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:aa="http://www.w3schools.com/MMMXXX">
<xsl:template match="/">
<html>
<body>
<h2>Things On The Shelf:</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Item Code</th>
<th style="text-align:left">Item Description</th>
<th style="text-align:left">Current Count</th>
<th style="text-align:left">On Order?</th>
</tr>
<xsl:for-each select="aa:StockList/aa:StockItem">
<tr>
<td><xsl:value-of select="aa:Item"/></td>
<td><xsl:value-of select="aa:Description"/></td>
<td><xsl:value-of select="aa:Count"/></td>
<td><xsl:value-of select="aa:Order"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
So what do I need to do to my XSLT and WHERE do I need to do it? I've attempted about 15 different 'apply templates' but while I manage to add the attribute I can't also add my html table? :(
Please help.
This has the ring of an XY problem. Just be assured that you cannot change your source document through XSLT, i.e. adding a new attribute to it so your existing stylesheet code could work. You also cannot produce an intermediate document and then transform that through XSLT 1.0 (at least as far as I know).
You have to do one of two things:
Modify whatever is generating the source XML so it correctly declares the namespace of <StockList> for you. You could do this like so:
using (MemoryStream ms = new MemoryStream())
{
dataSet.WriteXml(ms);
ms.Position = 0; // reset!
XDocument xd = XDocument.Load(ms);
XNamespace aa = "http://www.w3schools.com/MMMXXX";
foreach (var el in xd.Root.DescendantsAndSelf())
{
el.Name = aa.GetName(el.Name.LocalName);
}
xd.Root.Add(new XAttribute(XNamespace.Xmlns + "aa", aa);
xd.Save(ms); // or just return the XDocument.ToString(), or return XDocument.CreateReader() as desired
}
Modify your XSLT so that it doesn't care about namespaces. For example, change <xsl:for-each select="aa:StockList/aa:StockItem"> to <xsl:for-each select="*[local-name()='StockList']/*[local-name()='StockItem']"> and so on everywhere you have a select using that namespace prefix. This is probably the easier fix - I'd go with this solution myself.
If you want to apply two transformations in one style sheet with XSLT 1.0 where the first adds the namespace (you would need to add it to all elements) and the second transforms the result of the first to HTML then you need to perform one step with a variable that is a result tree fragment and then convert that result tree fragment to a node set to apply your for-each or other templates. Converting a result tree fragment to a node set can be done with most XSLT processors using the EXSLT extension function exsl:node-set (http://exslt.org/exsl/functions/node-set/index.html), however MSXML used by IE does not support that EXSLT function, only a similar function in a different namespace. Using the ms:script extension element it is however possible to have MSXML support exsl:node-set, so a complete style sheet doing two transformations looks like
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:aa="http://example.com/ns1"
xmlns:exsl="http://exslt.org/common"
xmlns:ms="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="aa exsl ms"
version="1.0">
<ms:script language="JScript" implements-prefix="exsl">
this['node-set'] = function(nodeList) {
return nodeList;
}
</ms:script>
<xsl:variable name="rtf1">
<xsl:apply-templates mode="add-namespace"/>
</xsl:variable>
<xsl:template match="*" mode="add-namespace">
<xsl:element name="aa:{local-name()}">
<xsl:copy-of select="#*"/>
<xsl:apply-templates mode="add-namespace"/>
</xsl:element>
</xsl:template>
<xsl:template match="/">
<html>
<body>
<h2>Things On The Shelf:</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Item Code</th>
<th style="text-align:left">Item Description</th>
<th style="text-align:left">Current Count</th>
<th style="text-align:left">On Order?</th>
</tr>
<xsl:for-each select="exsl:node-set($rtf1)/aa:StockList/aa:StockItem">
<tr>
<td><xsl:value-of select="aa:Item"/></td>
<td><xsl:value-of select="aa:Description"/></td>
<td><xsl:value-of select="aa:Count"/></td>
<td><xsl:value-of select="aa:Order"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The example is online at http://home.arcor.de/martin.honnen/xslt/test2015100701.xml respectively http://home.arcor.de/martin.honnen/xslt/test2015100701.xsl.
Works as intended with current versions of Firefox, Chrome and IE on Windows 10. Unfortunately Microsoft Edge complains about an error in the XSLT, I am not sure what causes this as Edge like IE 11 uses MSXML 6 to do XSLT. To make it work with Edge I rewrote the style sheet not to make use of ms:script and instead use function-available and xsl:when:
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:aa="http://example.com/ns1"
xmlns:exsl="http://exslt.org/common"
xmlns:ms="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="aa exsl ms"
version="1.0">
<xsl:variable name="rtf1">
<xsl:apply-templates mode="add-namespace"/>
</xsl:variable>
<xsl:template match="*" mode="add-namespace">
<xsl:element name="aa:{local-name()}">
<xsl:copy-of select="#*"/>
<xsl:apply-templates mode="add-namespace"/>
</xsl:element>
</xsl:template>
<xsl:template match="/">
<xsl:choose>
<xsl:when test="function-available('exsl:node-set')">
<xsl:apply-templates select="exsl:node-set($rtf1)/aa:StockList"/>
</xsl:when>
<xsl:when test="function-available('ms:node-set')">
<xsl:apply-templates select="ms:node-set($rtf1)/aa:StockList"/>
</xsl:when>
<xsl:otherwise>
<html>
<body>
<p>Your XSLT processor does not support exsl:node-set or ms:node-set.</p>
</body>
</html>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="/aa:StockList">
<html>
<body>
<h2>Things On The Shelf:</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th style="text-align:left">Item Code</th>
<th style="text-align:left">Item Description</th>
<th style="text-align:left">Current Count</th>
<th style="text-align:left">On Order?</th>
</tr>
<xsl:for-each select="aa:StockItem">
<tr>
<td><xsl:value-of select="aa:Item"/></td>
<td><xsl:value-of select="aa:Description"/></td>
<td><xsl:value-of select="aa:Count"/></td>
<td><xsl:value-of select="aa:Order"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
That way of course it works with Firefox, Chrome and IE as well.
Sorry if my Post won´t be so good i am not that good in expressing myself.
What i want:
I´ve got an XML and a XSL Data i want to convert to an XSLT for an HTML.
As transformating i use Altova XMLSpy and this webpage: http://www.freeformatter.com/xsl-transformer.html
What i´ve got:
My XML:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="Style.xsl"?>
<Configuration>
<Environment>
...
</Environment>
<Configurations>
...
<Config>
...
</Config>
</Configurations>
</Configuration>
My XSL:
<?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>
<table border="4">
<xsl:apply-templates select="Configuration"/>
</table>
</body>
</html>>
</xsl:template>
<xsl:template match="Environment">
<tr>Environment</tr>
<br/>
<td> <th>Text</th>
<xsl:value-of select="Environment"/>
</td>
<td> <th>Text2</th>
<xsl:value-of select="config"/>
</td>
...
...
</xsl:template>
</xsl:stylesheet>
This is just a example how i build it.
so far everything was fine, but then:
Problem:
If i start my XML in Firefox now everything works. If i start it in IE or Chrome i just get the XML Data but not the Table.
Trying to transform it in XSLT gives me this Error:
Unable to perform XSL transformation on your XML file. null
I hope you can help me. I am a bloody beginner in XML/XSl/XSLT but i hope my post will give you the Information you need.
Greetings
Max
You have made a very common beginner's mistake:
<xsl:template match="Environment">
<tr>Environment</tr>...
<xsl:value-of select="Environment"/>
In this template, the context node is an Environment element, and your xsl:value-of instruction is looking for a child of that element with the name Environment. But your Environment element (I assume) does not have any Environment children. What you should write (I assume) is
<xsl:value-of select="."/>
However, I don't think this is the whole problem. It doesn't account for all the symptoms described. You've actually made another beginner's mistake, which is trying to run your XSLT code in the browser before testing it elsewhere. The browser-based XSLT engines give lousy diagnostics (even when you use something like Firebug). Get your code working first in a desktop environment - preferably an XML IDE like oXygen. You'll then get a decent explanation of what is wrong.
Hi Here Is The Modified Version of Your Code.
XSL Template Match Must match the XML node you wish to apply templates.
<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:stylesheet version="2.0">
<xsl:template match="Configuration">
<html>
<body>
<table border="4">
<xsl:apply-templates select="Environment"/>
</table>
<table border="4">
<xsl:apply-templates select="Configurations"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="Environment">
<tr>
<th>
<xsl:value-of select="name()"/>
</th>
</tr>
<tr>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:template>
<xsl:template match="Configurations">
<tr>
<th>
<xsl:value-of select="name()"/>
</th>
</tr>
<tr>
<td>
<xsl:apply-templates select="Config"/>
</td>
</tr>
</xsl:template>
<xsl:template match="Config">
<tr>
<th>
<xsl:value-of select="name()"/>
</th>
</tr>
<tr>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
I want to change this xml content to HTML table
<SSI>
<data>
<expanded>Chemical Research</expanded><abbre>Chem. Res.</abbre>
<expanded>Materials Journal</expanded><abbre>Mater. J.</abbre>
<expanded>Chemical Biology</expanded><abbre>Chem. Biol.</abbre>
<expanded>Symposium Series</expanded><abbre>Symp. Ser.</abbre>
<expanded>Biochimica Polonica</expanded><abbre>Biochim. Pol.</abbre>
<expanded>Chemica Scandinavica</expanded><abbre>Chem. Scand.</abbre>
<\data>
<data>
<expanded>Botany</expanded><abbre>Bot.</abbre>
<expanded>Chemical Engineering</expanded><abbre>Chem. Eng.</abbre>
<expanded>Chemistry</expanded><abbre>Chem.</abbre>
<expanded>Earth Sciences</expanded><abbre>Earth Sci.</abbre>
<expanded>Microbiology</expanded><abbre>Microbiol.</abbre>
<\data>
<\SSI>
Tried with following XSL
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head><title>Abbreviate</title></head>
<body>
<table border="1">
<tr>
<th>Expanded</th>
<th>Abbre</th>
</tr>
<xsl:for-each select="SSI/data">
<tr>
<td><xsl:value-of select="expanded"/></td>
<td><xsl:value-of select="abbre"/></td>
</tr>
</xsl:for-each>
</table>
</body></html>
</xsl:template>
</xsl:stylesheet>
I got only the first entry of data tag in HTML Table format
Expanded Abbre
----------- --------------------
Chemical Research Chem. Res
Botany Bot.
how can get all the values in HTMl???
If you clean up your XSLT and use xsl:apply-templates rather than xsl:for-each, life will become simpler. There is almost never a reason to use xsl:for-each. Try this:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<html>
<head><title>Abbreviate</title></head>
<body>
<table border="1">
<tr>
<th>Expanded</th>
<th>Abbre</th>
</tr>
<xsl:apply-templates select='SSI/data/expanded'/>
</table>
</body></html>
</xsl:template>
<xsl:template match="expanded">
<tr>
<td><xsl:apply-templates/></td>
<xsl:apply-templates select='following-sibling::abbre[1]'/>
</tr>
</xsl:template>
<xsl:template match="abbre">
<td><xsl:apply-templates/></td>
</xsl:template>
</xsl:stylesheet>
By using small templates that are applied, you simplify your stylesheet. Additionally, there is no real reason to use xsl:value-of here - the built-in templates will do the right thing. You will end up with simpler templates that are easier to understand.