I have 2 files, file.xml and file.xsl that I have made. I am looking for how to see the result in a browser. From my research I have understood that only IE got an xml parser and that for the others browser I need a servor script.
I have also put these lines at the top of my xml file :
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Employe.xsl"?>
and these lignes at the top of my xsl file :
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
However, even when i'm using IE (11) I only have the text without any style that I have put.
I wanted to display the elemnts in a table but there isn't any.
I am giving you my code for the table if there is any mistakes I haven't found, but normaly it is ok.
Here is the xsl code :
<xsl:template match="/">
<html>
<body>
<h2>List of Workers</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th rowspan=3> ID </th>
<th colspan=5> Basic Information </th>
<th rowspan=3> Picture </th>
<th colspan=2> Skills enable </th>
</tr>
<tr>
<td rowspan=2> Name </td>
<td colspan=3> Address </td>
<td rowspan=2> Phone Number </td>
<td rowspan=2> Skill 1 </td>
<td rowspan=2> Skill 2 </td>
</tr>
<tr>
<td> Number </td>
<td> Street </td>
<td> Town </td>
</tr>
<xsl:for-each select="List_Of_Employe/Employe">
<xsl:sort select="Name"/>
<tr>
<td><xsl:value-of select="ID"/></td>
<td><xsl:value-of select="Basic_Information/Name"/></td>
<td><xsl:value-of select="Basic_Information/Address/Number"/></td>
<td><xsl:value-of select="Basic_Information/Address/Street"/></td>
<td><xsl:value-of select="Basic_Information/Address/Town"/></td>
<td><xsl:value-of select="Basic_Information/Phone_Number"/><td/>
<td><xsl:value-of select="Photo"/></td>
<td><xsl:value-of select="Skills_Enable/Skill_1"/></td>
<td><xsl:value-of select="Skills_Enable/Skill_2"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
and here is my xml code :
<List_Of_Employe>
<Employe>
<ID> 1235 </ID>
<Basic_Information>
<Name> James Bond</Name>
<Address>
<Number > 05 </Number>
<Street> Queen's street </Street>
<Town> London </Town>
</Address>
<Phone_Number> 07876543210 </Phone_Number>
</Basic_Information>
<Photo> James.png </Photo>
<Skills_Enable>
<Skill_1> XML </Skill_1>
<Skill_2> C# </Skill_2>
</Skills_Enable>
</Employe>
<Employe>
<ID> 1236 </ID>
<Basic_Information>
<Name> Sherlock Holmes </Name>
<Address>
<Number > 100 </Number>
<Street> Prince's street </Street>
<Town> London </Town>
</Address>
<Phone_Number> 07765432100 </Phone_Number>
</Basic_Information>
<Photo> Sherlock.png </Photo>
<Skills_Enable>
<Skill_1> JavaScript </Skill_1>
<Skill_2> Python </Skill_2>
</Skills_Enable>
</Employe>
</List_Of_Employe>
Hoping you will be able to help me
Mayeul
Your stylesheet needs some improvement, but you're not far off a solution. It's not a beautiful solution, but it successfully transforms your input XML. (A better solution would have used several templates, not a huge one with several for-each statements).
Clearing up a few things
You say:
From my research I have understood that only IE got an xml parser and that for the others browser I need a servor script
No, that's not true. Every major browser has a decent XML parser. You do not need any server-side code to parse XML. Likewise, every major browser (IE, Chrome, Firefox, Safari) ships with an XSLT processor, though only supporting XSLT 1.0.
However, even when i'm using IE (11) I only have the text without any style that I have put.
Getting nothing but all textual content from the input XML as the result of a transformation usually means: none of your templates could match the input elements. None of your code was applied, and the default action is taken: invoking the built-in templates, that only output all text nodes.
It's unclear to me why no templates should apply in your case, let me know whether the stylesheet I suggest below changes the output.
Stylesheet
I have made the following changes to your stylesheet:
There was a stray <td/> that should be </td>, because it ends a td element.
Added quotes to all attribute values. Attribute values absolutely need to be in quotes ("..."), since the XSLT code must itself be well-formed XML.
An HTML parser can deal with a lot of errors (e.g. unquoted attribute values), but XML parsers are very strict on this.
<?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>List of Workers</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th rowspan="3"> ID </th>
<th colspan="5"> Basic Information </th>
<th rowspan="3"> Picture </th>
<th colspan="2"> Skills enable </th>
</tr>
<tr>
<td rowspan="2"> Name </td>
<td colspan="3"> Address </td>
<td rowspan="2"> Phone Number </td>
<td rowspan="2"> Skill 1 </td>
<td rowspan="2"> Skill 2 </td>
</tr>
<tr>
<td> Number </td>
<td> Street </td>
<td> Town </td>
</tr>
<xsl:for-each select="List_Of_Employe/Employe">
<xsl:sort select="Name"/>
<tr>
<td><xsl:value-of select="ID"/></td>
<td><xsl:value-of select="Basic_Information/Name"/></td>
<td><xsl:value-of select="Basic_Information/Address/Number"/></td>
<td><xsl:value-of select="Basic_Information/Address/Street"/></td>
<td><xsl:value-of select="Basic_Information/Address/Town"/></td>
<td><xsl:value-of select="Basic_Information/Phone_Number"/></td>
<td><xsl:value-of select="Photo"/></td>
<td><xsl:value-of select="Skills_Enable/Skill_1"/></td>
<td><xsl:value-of select="Skills_Enable/Skill_2"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Also consider adding the following line to your stylesheet:
<xsl:output method="html" indent="yes"/>
To make it explicit that you'd like to output HTML.
XHTML Output
<html>
<body>
<h2>List of Workers</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th rowspan="3"> ID </th>
<th colspan="5"> Basic Information </th>
<th rowspan="3"> Picture </th>
<th colspan="2"> Skills enable </th>
</tr>
<tr>
<td rowspan="2"> Name </td>
<td colspan="3"> Address </td>
<td rowspan="2"> Phone Number </td>
<td rowspan="2"> Skill 1 </td>
<td rowspan="2"> Skill 2 </td>
</tr>
<tr>
<td> Number </td>
<td> Street </td>
<td> Town </td>
</tr>
<tr>
<td> 1235 </td>
<td> James Bond</td>
<td> 05 </td>
<td> Queen's street </td>
<td> London </td>
<td> 07876543210 </td>
<td> James.png </td>
<td> XML </td>
<td> C# </td>
</tr>
<tr>
<td> 1236 </td>
<td> Sherlock Holmes </td>
<td> 100 </td>
<td> Prince's street </td>
<td> London </td>
<td> 07765432100 </td>
<td> Sherlock.png </td>
<td> JavaScript </td>
<td> Python </td>
</tr>
</table>
</body>
</html>
Rendered Output
I do not have IE to try it out there, but Firefox renders the HTML output to:
Finally, let me be nit-picking for a brief moment, it really should read "Employee", not "Employe".
Related
Am trying to generating PDF out of XML document. Please find my below XML and XSL for the same.
Am expecting it should display all rows under tag but am getting only very first element (rows) in each tag.
Please find my below xml
<receipt>
<order>
<page></page>
<page>
<line_number>1</line_number>
<product_code>S10</product_code>
<line_number>2</line_number>
<product_code>S20</product_code>
<line_number>3</line_number>
<product_code>S92</product_code>
</page>
<page>
<line_number>6</line_number>
<product_code>S92</product_code>
<line_number>7</line_number>
<product_code>S31</product_code>
<line_number>8</line_number>
<product_code>S31</product_code>
</page>
</order>
</receipt>
Please find my xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml"
xmlns:date="http://exslt.org/dates-and-times" extension-element-prefixes="date">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="/receipt">
<html>
<head>
<style>#page {size: a4 landscape;}</style>
</head>
<body>
<table >
<thead>
<tr >
<th >Line</th>
<th>Item Code</th>
</tr>
</thead>
<xsl:for-each select="order/page" >
<tbody>
<tr style="font-size: 9px; ">
<td ><xsl:value-of select="line_number" /></td>
<td ><xsl:value-of select="product_code" /></td>
</tr>
</tbody>
</xsl:for-each>
</table>
<br />
</body>
</html>
</xsl:template>
</xsl:stylesheet>
In the output only 1st element in tag is coming instead of all the elements (rows) under each tag.
for example :
output :
1 s10
6 s92
Expected Output
1 s10
2 s20
3 s92
6 s92
7 s31
8 s31
You want to output one row per line_number, rather that one row per page, so you xsl:for-each needs to select these line_number elements
<xsl:for-each select="order/page/line_number">
Then to get the value of the line_number and following product_code, do this...
<td><xsl:value-of select="." /></td>
<td><xsl:value-of select="following-sibling::product_code[1]" /></td>
Try this...
<xsl:template match="/receipt">
<html>
<head>
<style>#page {size: a4 landscape;}</style>
</head>
<body>
<table >
<thead>
<tr>
<th>Line</th>
<th>Item Code</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="order/page/line_number">
<tr style="font-size: 9px; ">
<td><xsl:value-of select="." /></td>
<td><xsl:value-of select="following-sibling::*[1][self::product_code]" /></td>
</tr>
</xsl:for-each>
</tbody>
</table>
<br />
</body>
</html>
</xsl:template>
Note that this does make the assumption that each line_number will be followed by a product_code.
(I have also moved the creation of the tbody element outside the xsl:for-each as you should really only have one such element in your table, rather than one for each row)
Here is my XML File:
XML contains disk space information of hosts.
`<disk>
<host name="host1">
<partitions>
<partition>/par1</partition>
<diskUsed>60%</diskUsed>
</partitions>
<partitions>
<partition>/par2</partition>
<diskUsed>70%</diskUsed>
</partitions>
</host>
<host name="host2">
<partitions>
<partition>/par1</partition>
<diskUsed>80%</diskUsed>
</partitions>
<partitions>
<partition>/par2</partition>
<diskUsed>90%</diskUsed>
</partitions>
</host>
</disk>`
I want to display as below in html
I was not able to read them by column wise, can you please suggest any ways to do this?
<table>
<tr>
<td>host1</td>
<td>host2</td>
</tr>
<tr>
<td>par1</td>
<td>60%</td>
<td>80%</td>
</tr>
<tr>
<td>par2</td>
<td>70%</td>
<td>90%</td>
</tr>
</table>
Any ideas how it can be done using XSLT?
Sorry Below is the XSL code tried. I cannot copy the code i wrote(in client env). So re-wrote it, sorry for the trouble.
<xsl:variable name="disks" select="disk"/>
<table id="disk">
<tr>
<xsl:foreach select="$disk">
<th><xsl:value-of select="#name"/></th>
</xsl:foreach>
</tr>
<tr>
<xsl:for-each select="$disk">
<xsl:for-each select ="partitions">
<td><xsl:value-of select="diskUsed"/></td>
</xsl:for-each>
</xsl:for-each>
here i am not able to print the partitions name
I have an XML file which i got by exporting a database. now i need to show the xml data in html page as a table. to do so, i have to check the corresponding values for a particular data in the XML file from an XSLT file. since my database is a bit complicated, i am facing difficulties in checking the multiple values of differnt nodes and selecting a corresponding values from another node of the xml file. e.g. i have the following xml data-
<?xml-stylesheet type='text/xsl' href='myXSL.xsl'?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name1>
<names>
<id>5</id>
<class>space</class>
<from>Germany</from>
<fm>
<id>9</id>
<names>5</names>
<name>Vienna</name>
</fm>
<fm>
<id>10</id>
<names>5</names>
<name>Prague</name>
</fm>
</names>
</name1>
<FFrom>
<effect>
<id>11</id>
<DVV>1</DVV>
<SAT>0</SAT>
<DDCC>0</DDCC>
<name>SAA Name</name>
</effect>
<effect>
<id>23</id>
<DVV>0</DVV>
<SAT>0</SAT>
<DDCC>1</DDCC>
<name>SAA Name2</name>
</effect>
</FFrom>
<name2>
<newNames>
<id>1</id>
<name>VSSS Name</name>
<route1>
<id>5</id>
<identifyer>C</identifyer>
<function>abc</function>
<names>4</names>
<naviagtes2>
<id>9</id>
<fm>7</fm>
<effect>2</effect>
</naviagtes2>
<naviagtes2>
<id>10</id>
<fm>8</fm>
<effect>5</effect>
</naviagtes2>
</route1>
</newNames>
<newNames>
<id>6</id>
<name>VEE Name</name>
<route1>
<id>18</id>
<identifyer>C0</identifyer>
<function>abc</function>
<names>5</names>
<naviagtes2>
<id>68</id>
<fm>9</fm>
<effect>11</effect>
</naviagtes2>
<naviagtes2>
<id>69</id>
<fm>10</fm>
<effect>7</effect>
</naviagtes2>
</route1>
</newNames>
</name2>
</root>
I used the following xslt codes
<?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>
<head><title>title</title>
<style type="text/css">
body {
font: 10px Verdana, sans-serif;
color: #000000;
margin: 0;
padding: 0;
}
tr.header2 {
font-style:italic;
}
tr.newNames{
background-color:#6495ED;
margin-top:4px;
}
</style>
</head>
<body><h1><xsl:value-of select="Title" /></h1>
<table width="800px" class="table" cellspacing="0px">
<xsl:for-each select="root/name2/newNames">
<tr class="newNames"><td colspan="12">
<b>NNavigate:</b> <xsl:value-of select="name"/><br/>
<b>NMNaviagate:</b> <xsl:value-of select="route1/function"/>
</td></tr>
<xsl:for-each select="/root/name1/names">
<tr class="names"><td colspan="12">
<b> CClass: </b><xsl:value-of select="class" />
<b> FFrom: </b><xsl:value-of select="from" />
</td></tr>
<tr class="header2">
<td>Route</td>
<td>From</td>
<td align="center">SA</td>
<td align="center">DB</td>
</tr>
<xsl:for-each select="fm">
<tr>
<td class=""><xsl:value-of select="name" /></td>
<td class=""><xsl:value-of select="/root/FFrom/effect/name" /></td>
<td class=""><xsl:value-of select="/root/FFrom/effect/SAT" /></td>
<td class=""><xsl:value-of select="/root/FFrom/effect/DVV" /></td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
I am stuck in the following point.
if you notice there are fm nodes, effect nodes and naviagtes2 nodes.
in my html page, there will be a table where values of first column come from fm nodes (root/name1/names/fm/name) and values of second column come from effect nodes (root/FFrom/effect/name). in the naviagtes2 nodes, there are fm and effect elements which are equivalent to fm/id and effect/id. that is, naviagtes2 nodes are used to check which values of effect/name will be against fm/name in the table. conditions are like following
root/name1/names/fm/name against root/FFrom/effect/name if
root/name1/names/fm/id = root/name2/newNames/route1/naviagtes2/fm and
root/FFrom/effect/id = root/name2/newNames/route1/naviagtes2/effect
i am new in XSLT programming. Could anyone give me any clue please how to solve that in XSLT ?
in the naviagtes2 nodes, there are fm and effect elements which are
equivalent to fm/id and effect/id. that is, naviagtes2 nodes are used
to check which values of effect/name will be against fm/name in the
table.
I am afraid I still don't understand your question, but in an effort of moving this forward, I'll take a stab (in the dark?) at it.
The following stylesheet uses keys to link each naviagtes2 node to the fm and effect elements whose ids are listed in the naviagtes2 node. Thus each naviagtes2 node creates a {fm,effect} "pair" and these pairs are listed in the resulting table, along with the values fetched from the paired elements:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="fm" match="name1/names/fm" use="id" />
<xsl:key name="effect" match="FFrom/effect" use="id" />
<xsl:template match="/">
<table border="1" >
<tr>
<th>id</th>
<th>fm id</th>
<th>effect id</th>
<th>fm name</th>
<th>effect name</th>
</tr>
<xsl:for-each select="root/name2/newNames/route1/naviagtes2">
<tr>
<td><xsl:value-of select="id" /></td>
<td><xsl:value-of select="fm" /></td>
<td><xsl:value-of select="effect" /></td>
<td><xsl:value-of select="key('fm', fm)/name" /></td>
<td><xsl:value-of select="key('effect', effect)/name" /></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
when applied to your example input, the result is:
<?xml version="1.0" encoding="UTF-8"?>
<table border="1">
<tr>
<th>id</th>
<th>fm id</th>
<th>effect id</th>
<th>fm name</th>
<th>effect name</th>
</tr>
<tr>
<td>9</td>
<td>7</td>
<td>2</td>
<td/>
<td/>
</tr>
<tr>
<td>10</td>
<td>8</td>
<td>5</td>
<td/>
<td/>
</tr>
<tr>
<td>68</td>
<td>9</td>
<td>11</td>
<td>Vienna</td>
<td>SAA Name</td>
</tr>
<tr>
<td>69</td>
<td>10</td>
<td>7</td>
<td>Prague</td>
<td/>
</tr>
</table>
which in HTML would be rendered as:
Hopefully this gets you closer to your goal.
I'm really new to xslt so I would be very thankful if someone can help me...
I have a XML like this:
<dummy>
<element name="O">
<description/>
</element>
<element name="L">
<description>abstract for L</description>
</element>
<element name="Sd">
<description>Description for Sd</description>
</element>
<element name="Dh">
<description/>
</element>
<element name="P">
<description/>
</element>
<element name="S">
<description>Some description for S</description>
</element>
<element name="A">
<description/>
</element>
<L>2010</L>
<A>58.78</A>
<O>O</O>
<Sd>1101</Sd>
<S>0.00</S>
<A>368.38</A>
<L>2009</L>
<Sd>1103</Sd>
</dummy>
I have to had a final html table like this ( using xslt "1.0"):
<tr>
<td>
I have to select only non element tags one by one, and then replace the tag with the
description of the same element name (in case that decription does not exists then display only element name).
</td>
<td>
Value of non element tag
</td>
</tr>
4 example ( upper xml)
[in something like for-each]: take <L> 2010 </L>
then search for element name = "L" ( if description exists = true take
description else "L") and
display abstract for L 2010
So the final output 4 given xml should be:
<tr><td> abstract for L </td> <td> 2010 </td> </tr>
<tr><td> A </td> <td> 58.78 </td> </tr>
<tr><td> O </td> <td> O </td> </tr>
<tr><td> Description for Sd </td> <td> 1101 </td> </tr>
<tr><td> Some description for S </td> <td> 0.00 </td> </tr>
<tr><td> A </td> <td> 368.38 </td> </tr>
<tr><td> abstract for L </td> <td> 2009</td> </tr>
<tr><td> Description for Sd </td> <td> 1103 </td> </tr>
The xslt must be written in xslt = "1.0"
I think you could make use of a key here, to look up your element nodes by the name attribute
<xsl:key name="elements" match="element" use="#name" />
Firstly, you would need to match all your non-element nodes, like so
<xsl:apply-templates select="dummy/*[not(self::element)]" />
Then to look up the description of the matching element you could then use the key set up earlier
<xsl:apply-templates select="key('elements', local-name())"/>
You would have two matching templates for the element nodes in this case; one for element nodes with a description, and one for those without.
Here is the full XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes"/>
<xsl:key name="elements" match="element" use="#name"/>
<xsl:template match="/">
<table>
<xsl:apply-templates select="dummy/*[not(self::element)]"/>
</table>
</xsl:template>
<xsl:template match="*[not(self::element)]">
<tr>
<td>
<xsl:apply-templates select="key('elements', local-name())"/>
</td>
<td>
<xsl:value-of select="."/>
</td>
</tr>
</xsl:template>
<xsl:template match="element">
<xsl:value-of select="#name"/>
</xsl:template>
<xsl:template match="element[description[node()]]">
<xsl:value-of select="description"/>
</xsl:template>
</xsl:stylesheet>
When applied to your sample XML, the following HTML is output:
<table>
<tr>
<td>abstract for L</td>
<td>2010</td>
</tr>
<tr>
<td>A</td>
<td>58.78</td>
</tr>
<tr>
<td>O</td>
<td>O</td>
</tr>
<tr>
<td>Description for Sd</td>
<td>1101</td>
</tr>
<tr>
<td>Some description for S</td>
<td>0.00</td>
</tr>
<tr>
<td>A</td>
<td>368.38</td>
</tr>
<tr>
<td>abstract for L</td>
<td>2009</td>
</tr>
<tr>
<td>Description for Sd</td>
<td>1103</td>
</tr>
</table>
It involves selecting the 'letter' named elements using name() in the predicate:
<xsl:template match="element">
<xsl:param name='name' select="#name" />
<td><xsl:value-of select="description" /></td>
<td><xsl:value-of select="//*[name() = $name]" /></td>
</xsl:template>
Say I have an xml document consisting of a list as shown below:
<Items>
<Item>First Item</Item>
<Item>Second Item</Item>
<Item>Third Item</Item>
<Item>4</Item>
<Item>Five</Item>
</Items>
I want to convert it to a html table with two columns for the Item elements (I'm not fussed at the moment whether it's ordererd top-bottom-left-right or left-right-top-bottom).
<table>
<tr>
<td>First Item</td>
<td>Second Item</td>
</tr>
<tr>
<td>Third Item</td>
<td>4</td>
</tr>
<tr>
<td>Five</td>
<td></td>
</tr>
</table>
I understand I can get a table with a single column with the following xslt transform, but can't figure out how to get multiple columns.
<table>
<xsl:for-each select="Items">
<tr>
<td><xsl:value-of select="Item"/></td>
</tr>
</xsl:for-each>
</table>
Try this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/Items">
<table>
<xsl:for-each select="Item[position() mod 2 = 1]">
<xsl:variable name="pos" select="position() - 1" />
<tr>
<td><xsl:value-of select="."/></td>
<td><xsl:value-of select="//Item[position() = ($pos * 2) + 2]"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>