Multiple XSL files combination - html

Hi I have two xsl files and I have one xml how can I combine these xsl files together at transform type and combine them it and get one html
index.html
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE xsl:stylesheet [<!ENTITY nbsp " "><!ENTITY bull "•">]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:include href="hello.xsl"/>
<xsl:template match="/">
<html>
<tr>
<td><xsl:value-of select="name" /></td>
</tr>
</html>
</xsl:template>
</xsl:stylesheet>
and then my send xsl is
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE xsl:stylesheet [<!ENTITY nbsp " "><!ENTITY bull "•">]>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<table>
<tr>
<td><xsl:value-of select="age" /></td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
and my xml is
<xml>
<name>abc</name>
<age>15</age>
</xml>
What I want output is like
<html>
<tr><td>abc</td></tr>
<table>
<tr><td>15</td></tr>
</table>
</html>
Is that is do able thing to perform in xsl I search so many site but couldn't find answer, plz help

EDIT: You edited your question and are now asking something completely different.
As I said, you can combine templates and other element from separate stylesheets with xsl:include and xsl:import. See the relevant section of the specification here.
There are ways to combine separate stylesheets (e.g. via xsl:include and xsl:import), but in your case I do not think it is even necessary.
Your stylesheets only have one template each and they simply retrieve values from an input XML which is a trivial action. There is really no need to store those two templates in separate stylesheets.
Write one stylesheet that produces both the html element and the table.
Let me emphasize another thing: It is evident in your question that you do not really understand the workings of both XSLT and HTML. To give a few hints:
the output you request is malformed HTML. A tr element cannot be an immediate child of html. Content must be placed inside body, as opposed to header.
both of the templates you show match /. Obviously, it makes no sense to combine them if they match the same node.
Please take the time to study the basics of XSLT and HTML before asking a new question.
Stylesheet
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:output method="html" indent="yes"/>
<xsl:template match="/xml">
<html>
<body>
<table border="solid">
<tr>
<xsl:for-each select="*">
<td>
<xsl:value-of select="name()"/>
</td>
</xsl:for-each>
</tr>
<tr>
<td>
<xsl:value-of select="*[1]"/>
</td>
<td>
<xsl:value-of select="*[2]"/>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Output
<html>
<body>
<table border="solid">
<tr>
<td>name</td>
<td>age</td>
</tr>
<tr>
<td>abc</td>
<td>15</td>
</tr>
</table>
</body>
</html>

Related

XSLT template to match multiple nodes is repeating the html

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.

xsl template is overriding with xsl include

I am trying to create some reusable templates while developing a html page for xml with xsl. But when I include the other xsl's, the main xsl template is getting overridden instead of adding it to it. please suggest.
Here is my xml,
<employee>
<address>
<street>street1</street>
<city>city1</city>
<doornumber>1-23</doornumber>
<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>
<data>
<name>data1</name>
</data>
<data>
<name>data2</name>
</data>
<data>
<name>data3</name>
</data>
<data>
<name>data4</name>
</data>
<data>
<name>data5</name>
</data>
</employee>
Here is my main xsl,
<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:include href="test_include1.xsl" /> -->
<!-- <xsl:include href="test_include2.xsl" /> -->
</xsl:stylesheet>
Here is my test_include1.xsl,
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="employee">
<table><tr>
<th>data names</th></tr>
<xsl:for-each select="data">
<tr>
<td>
<xsl:value-of select="name"/>
</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
Here is my test_include2.xsl,
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="employee">
<table><tr>
<th>Name</th>
<th>College</th></tr>
<tr>
<td>
<xsl:value-of select="personalinfo/name"/>
</td>
<td>
<xsl:value-of select="remarks/education/college"/>
</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
I am trying to modularize the same xml data in different templates so that I can reuse the same templates in other stylesheets. Please suggest how I can acheive this. Thank you.
Here is the expected result,
<html><body>
<table>
<tr>
<th>Name</th>
<th>College</th>
<th>City</th>
</tr>
<tr>
<td>testname1</td>
<td>college1</td>
<td>city1</td>
</tr>
</table>
<table>
<tr><th>data names</th></tr>
<tr><td>data1</td></tr>
<tr><td>data2</td></tr>
<tr><td>data3</td></tr>
<tr><td>data4</td></tr>
<tr><td>data5</td></tr>
</table>
<table>
<tr>
<th>Name</th>
<th>College</th>
</tr>
<tr>
<td>testname1</td>
<td>college1</td>
</tr>
</table>
</body></html>
Firstly, I don't see any xsl:include declarations in any of these stylesheets, so I'm not quite sure what you are doing. [Sorry - missed the pale grey commented out code - poor contrast on my monitor.]
Secondly, with XSLT 1.0 the behaviour when you have two templates matching the same node, with the same precedence and priority, is not very well defined. Technically it's an error, but the processor is allowed to recover by choosing the rule that comes "last in the stylesheet" - which itself is not particularly well defined when there are multiple modules involved.
Thirdly, you say "the main xsl template is getting overridden instead of adding it to it". This suggests you have some particular expectation of how you want it to behave, but I can't really work out what this expectation is. You haven't given any expected results, so I don't know what you are trying to achieve. But it will always be the case, if you have more than one rule that matches a node, that you either get an error, or exactly one of the rules is executed - they are never combined in any way.
This could be achieved by modes.
Another way is to give each xsl:template match a priority number. The one which you want to get executed should have the highest priority. Priority is attribute of xsl:template
<xsl:template match = "employee" priority = "4"> do the task </xsl:template>

How to parse the xml data into html?

Here is my xml:
<Catalog>
<catalogDetail catalogId="DemoCatalog">
<catalogName>Demo Catalog</catalogName>
</catalogDetail>
<catalogDetail catalogId="GoogleCatalog">
<catalogName>Google Catalog</catalogName>
</catalogDetail>
</Catalog>
I want it to be read in HTML file how can I do this???
To do this your HTML file should contain some JavaScript code, so you will want to learn how to parse XML in Javascript.
Here is a good StackOverflow question on this topic: XML parsing in JavaScript
You can do by using PHP's XML Library called simplexml for more information check this link
http://www.w3schools.com/php/php_xml_simplexml.asp
NOTE : If you can elaborate on what technology you're using, I'll try to provide a more complete example.
I would suggest using XSLT for this. With XSLT, you can pass in the XML fragment, parse it, and return formatted HTML.
Here's an example XSLT document that converts XML to HTML:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="html" indent="yes"/>
<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>

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.

Transforming XML into HTML (as opposed to xhtml)

i want to transform some xml into HTML that has the following format:
<TR><TD> col1 <TD> col2 <TD> col3 </TR>
Note: The output is HTML, complete with optional closing tags omitted. This is the problem, and the reason the question exists.
A snippet of the XSL i'm using is:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
doctype-system='http://www.w3.org/TR/html4/strict.dtd'
doctype-public='-//W3C//DTD HTML 4.01//EN'
indent='yes'
method='html'
/>
...
<xsl:for-each select="/">
<TR><TD><xsl:value-of select="col1"/><TD><xsl:value-of select="col2"/><TD><xsl:value-of select="col3"/></TR>
</xsl:for-each>
You can see that the guts of the XSL matches my desired HTML (wrapped for easy reading):
<TR> <TD><xsl:value-of select="Column1"/>
<TD><xsl:value-of select="Column2"/>
<TD><xsl:value-of select="Column3"/> </TR>
Note: Those of you who know the error i'm getting from the XSLT: hopefully already know the answer.
When presented with my XSL (which, don't forget, is a form of xml), i get the non-well formed error:
End tag 'TR' does not match the start tag 'TD'.
This makes perfect sense. Indeed:
<TD><xsl:value-of select="Column3"/> </TR>
i do not close the TD element before closing the TR. So the question is:
How can i transform xml into HTML, given that HTML is not xml?
See also
HTML: Include, or exclude, optional closing tags?
XSLT: Transforming into non-xml content?
Omitting optional tags of html
Update one
It has been suggested that one could simply include the closing tags anyway, in order to make the XSL validate (shown wrapped for easy reading):
<TR> <TD><xsl:value-of select="col1"/></TD>
<TD><xsl:value-of select="col2"/></TD>
<TD><xsl:value-of select="col3"/></TD> </TR>
then, by using xsl:output method='html', the final HTML content would have the </TD> tags magically omitted. Except it doesn't work:
<TR><TD>col1</TD><TD>col2</TD><TD>col3</TD></TR>
Update two
It has been suggested that i give up, don't bother asking this question, and just include the optional closing tags. That's possible, but that's not my question. Also, the "solution" doesn't work for elements where the closing tag is forbidden, e.g.:
<BR/>
or
<BR></BR>
How would i include a <BR> element in my HTML output, given that it is forbidden in HTML to close a <BR> element.
Here's one way to do this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/*">
<TR><TD><xsl:value-of select="col1"/><TD><xsl:value-of select="col2"/><TD><xsl:value-of select="col3"/></TR>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the following XML document:
<t>
<col1>1</col1>
<col2>2</col2>
<col3>3</col3>
</t>
the wanted result is correctly produced:
<TR><TD>1<TD>2<TD>3</TR>
I believe the simplest thing is to just accept you're going to have closing tags in the output. While they might be optional, I believe most people would agree that best practice is to include them.
Is there a reason you really don't want optional closing tags in the output?
Re Update Two
There's no problem with this update. With method="html" <BR/> will be output as <BR>:
XSLT (note <BR/>):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
doctype-system='http://www.w3.org/TR/html4/strict.dtd'
doctype-public='-//W3C//DTD HTML 4.01//EN'
indent='yes'
method='html'
/>
<xsl:template match="/">
<HTML><BODY>
<TR>
<xsl:apply-templates/>
</TR>
<BR/> <!-- HERE -->
</BODY></HTML>
</xsl:template>
<xsl:template match="item">
<TD><xsl:value-of select="."/></TD>
</xsl:template>
</xsl:stylesheet>
Input:
<root>
<item>one</item>
<item>two</item>
</root>
Output (note <BR>):
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<HTML><BODY>
<TR>
<TD>one</TD>
<TD>two</TD>
</TR>
<BR> <!-- HERE -->
</BODY></HTML>
Have you tried the output as "HTML"? Elements that shouldn't be self-closed in HTML are not (i.e. <BR>, <img>).
If you still don't like how the XSLT engine is serializing HTML output, then you could set your <xsl:output method="text"> and construct the "HTML" that you want:
<TR><TD><xsl:value-of select="col1"/><TD><xsl:value-of select="col2"/><TD><xsl:value-of select="col3"/></TR>
which produces:
<TR><TD>col1<TD>col2<TD>col3</TR>
Ian, have you tried <xsl:output method="text">?
http://www.w3schools.com/xsl/el_output.asp