Showing images from xml link via xslt - html

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>

Related

How to combine multiple xml and prepare XSLT for the combined XML The above is the XSLT for one XML

How to combine multiple XML and prepare XSLT for the combined XML?
I tried to combine multiple XML into one and tried to prepare XSLT transformation for that one. The above is the XSLT for one XML. Need to prepare XSLT for the combined XML.
XML-1
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
</cd>
</catalog>
XML-2
<?xml version="1.0" encoding="UTF-8"?>
<catalog>
<cd>
<title>Empire Burlesque-1</title>
<artist>Bob Dylan-1</artist>
</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 style="text-align:left">Details</th>
<th style="text-align:left">XML-1</th>
</tr>
<tr>
<xsl:for-each select="catalog/cd">
​ <td>Title</td>
​ <td><xsl:value-of select="title"/></td>
</xsl:for-each>
</tr>
​<tr>
​ <xsl:for-each select="catalog/cd">
<td>Artist</td>
<td><xsl:value-of select="artist"/></td>
</xsl:for-each>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
The above is the XSLT for one XML. Need to prepare XSLT for the combined XML
[1]: https://i.stack.imgur.com/g8ce7.jpg
Change <xsl:for-each select="catalog/cd"> to e.g. <xsl:for-each select="catalog/cd | document('XML-2.xml')/catalog/cd">, to process the second document as well.

Processing Dynamically Created Children and Siblings' Children

I've been editing and looking at this for so long I'm failing to find a seemingly easy solution.
An element (and its sibling) will have any number of different (dynamic) results, which I would like to display in an HTML table, one row for each cd-file pair. Initially thinking I could avoid for-each loops (which seem to return the same results anyway), I need a [better] way to refer to the children. The source below is similar in structure with which I'm working.
For example, some "cd"s and "file"s will have more elements such as price, some might have no information.
XML
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.test2.xsl"?>
<catalog>
<rock>
<album>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
</cd>
<file>
<store>Apple</store>
<size>3823</size>
</file>
</album>
<album>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
</cd>
<file>
<store>Amazon</store>
<size>2123</size>
</file>
</album>
</rock>
</catalog>
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.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="#cccccc">
<th style="text-align:left">Title</th>
<th style="text-align:left">Artist</th>
<th style="text-align:left">Store</th>
<th style="text-align:left">Size</th>
</tr>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="album">
<tr>
<xsl:apply-templates select="cd"/>
<xsl:apply-templates select="file"/>
</tr>
</xsl:template>
<xsl:template match="cd">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
<xsl:template match="file">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
</xsl:stylesheet>
Results
<table border="1">
<tbody>
<tr bgcolor="#cccccc">
<th style="text-align:left">Title</th>
<th style="text-align:left">Artist</th>
<th style="text-align:left">Store</th>
<th style="text-align:left">Size</th>
</tr>
<tr>
<td>
Empire Burlesque
Bob Dylan
</td>
<td>
Apple
3823
</td>
</tr>
<tr>
<td>
Hide your heart
Bonnie Tyler
</td>
<td>
Amazon
2123
</td>
</tr>
</tbody>
</table>
Result View
Now, I think I see what is happening. From my interpretation, in the XSLT file, under the "cd" and "file" templates, select="." is returning all the children inside the <td>. I need a way for each to have a <td>. I've tried such things as call-template for each "cd" and "file," as well as for-each within the "cd" and "file" templates. Note that I also need to dynamically build the <th> elements, for now they're created manually for testing purposes. Any suggestions?
As an educated guess (it is not exactly clear what your expected output looks like, and what aspects of the input file are variable), I think you want the following.
There is no need to explicitly apply templates to the cd and title elements, just apply-templates in a general fashion. Also, your stylesheet is currently missing templates for store, size etcetera. As far as I understand, those are the element whose content should go inside td elements in the HTML output, so you need to match them with templates, even if those templates are rather general.
If you do not know the names of the table headers th beforehand and if there is a variable number of leaf elements that are grandchildren of album, here is a more "dynamic" solution:
XSLT Stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.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:strip-space elements="*"/>
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#cccccc">
<xsl:for-each select="distinct-values(catalog/rock/album/*/*/name())">
<th style="text-align:left">
<xsl:value-of select="."/>
</th>
</xsl:for-each>
</tr>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="album">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="album/*/*">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
</xsl:stylesheet>
HTML Output
<!DOCTYPE html
PUBLIC "XSLT-compat">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#cccccc">
<th style="text-align:left">title</th>
<th style="text-align:left">artist</th>
<th style="text-align:left">store</th>
<th style="text-align:left">size</th>
</tr>
<tr>
<td>Empire Burlesque</td>
<td>Bob Dylan</td>
<td>Apple</td>
<td>3823</td>
</tr>
<tr>
<td>Hide your heart</td>
<td>Bonnie Tyler</td>
<td>Amazon</td>
<td>2123</td>
</tr>
</table>
</body>
</html>
Rendered HTML
Try this solution online here.
If I'm guessing correctly, you want to do something like:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:template match="/catalog">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr>
<xsl:apply-templates select="*/album[1]" mode="header"/>
</tr>
<xsl:apply-templates/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="album">
<tr>
<xsl:apply-templates/>
</tr>
</xsl:template>
<xsl:template match="*[text()]" mode="header">
<th>
<xsl:value-of select="name()"/>
</th>
</xsl:template>
<xsl:template match="*[text()]">
<td>
<xsl:value-of select="."/>
</td>
</xsl:template>
</xsl:stylesheet>
This create a row for every album, and a column for every leaf node with a text node.
Note that this assumes that your input is regular - i.e. that every album has the same properties, in the same order, and none of them is empty.

Output not shown as XML table in Internet Explorer

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="/">
...

XML + XSL to XSLT for an HTML

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>

To transform XML to HTML in table format

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.