How to transform JSON with XSLT? - json

I have the following XSLT file that is already working with the XML file we have on ActiveMQ. The thing is that we are upgrading the system and we don't have the XML view anymore. Instead we have an URL that return in JSON the queue informations.
<?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>
<h2>PROJECT Notification</h2>
<div style="width:600px;background-color:#e5eecc;border:1px solid #98bf21;margin:10px;">
<table border="1" style="border-style:dashed">
<tr bgcolor="#9acd32">
<th width="300px;">Queue Name</th>
<th>Queue Size</th>
</tr>
<xsl:apply-templates select="queues" />
</table>
</div>
</body>
</html>
</xsl:template>
<xsl:template match="queue">
<tr>
<td><xsl:value-of select="#name"/></td><td><xsl:value-of select="./stats/#size" /></td>
</tr>
</xsl:template>
</xsl:stylesheet>
I want to know if that's possible to keep using this same XSLT file, just modifying the tags to start reading from the JSON URL instead.
I'm using camel to route to this XSLT, but I didn't want to create a Processor to convert the JSON to XML. Instead I want to use the JSON right away.

XSLT operates on XML input, not JSON input. (While you could parse JSON using XSLT 2.0 string processing facilities, it's still not the right tool for the job.)
Your HTML target is quite simple, so migrating away from XML/XSLT shouldn't be as much of a challenge as it could have otherwise been. Look into a JavaScript-based templating engine such as Mustache.js, Handlebars.js, Underscore.js, Hogan.js...

Related

XSLT disable-ouput-escaping not escaping character <

In the following stylesheet:
<?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>
<h1>Music Collection:</h1>
<table border="1">
<tr bgcolor="#9acd32">
<th>Title</th>
<th>Artist</th>
</tr>
<tr>
<td><xsl:value-of select="catalog/cd/title" disable-output-escaping="yes" /></td>
<td><xsl:value-of select="catalog/cd/artist" /></td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Why does it not convert the < to < when used with the following HTML?
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<catalog>
<cd>
<title>Empire Burlesque < </title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia </company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>
The output can be tested here.. http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=tryxsl_value-of
Edit
Here is another example where it does not work
<xsl:for-each select="//productType">
<xsl:value-of select="." disable-output-escaping="yes" />
<br></br>
</xsl:for-each>
With the DOE the < get stripped out. Without it i can see the < character (Using XSLT 1.0)
disable-output-encoding was an optional feature in XSLT 1 (and is deprecated in XSLT 2) so a processor is allowed to ignore it. In particular it is almost always ignored in any processing pipeline in which the output from XSLT is passed as an in-memory tree (a DOM node for example) to a following application which then serialises the XML. d-o-e is essentially a hint to the XSLT serialisation phase and in such a processing pipeline XSLT serialisation is not used.
It is something processor-related (a bug I'd say) - using the .NET XSLT processor in Visual Studio I get < as expected, and I get < if I remove disable-output-escaping="yes"
The effect of disable-output-escaping depends on what processor you are using and on the way in which you are using it. You haven't given us enough information to answer these questions.
More pertinently, why are you using it? What problem are you trying to solve? Usually, when people use disable-output-escaping, they are going about things the wrong way - there's a better approach available. There are some cases where d-o-e is appropriate, but it means you can only use the stylesheet with a processor that supports it, in a pipeline where you know that the stylesheet's result tree is being piped straight into a serializer rather than into some other tree-consuming process.

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>

Trying to link use XSL to output a HTML table from XML

I'm trying to use a .xsl file so that it will return a HTML table of the XML document. I have no experience with this and it is something I've not done before so it's probably this is just a simple mistake.
I have the following code for my podcatalog.xsl
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Tranform">
<xsl:template match="/">
<html>
<body>
<h2>Pods Papers</h2>
<table border="1">
<tr bgcolor="#9ACD32">
<th>Author</th>
<th>Title</th>
<th>Pages</th>
<th>Year</th>
</tr>
<xsl:for-each select="pods-papers/inproceedings">
<tr>
<td><xsl:value-of select="author"/></td>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="pages"/></td>
<td><xsl:value-of select="year"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
And the podcatalog.xml can be found here
The error I am getting is: "Error loading stylesheet: Parsing an XSLT stylesheet failed."
Change:
<xsl:for-each select="pods-papers/inproceedings key">
to:
<xsl:for-each select="pods-papers/inproceedings">
'key' is an attribute of element
It looks like you’re defining entities the wrong way (<!ENTITY Aring "&#197;" > should have & instead of &) and, more seriously, without a DTD. It appears to be a longstanding request that we should be able to do that, but... So the problem is that your XML file has a DOCTYPE declaration that contains just entity definitions, not a document type definition.
The options appear to be:
Write a DTD. Some work, but might be useful for documentation purposes.
Replace the entity references by the characters themselves or by character references, e.g. Ö by Ö or by Ö.

I want to link my XML file to my HTML page

I have created a XML file I would like for it to be displayed in my HTML page that I also created. Can someone tell me how to do this.
<?xml version="1.0"?>
<Family>
<Mom>Alison</Mom>
<age>44</age>
<son>Ian</son>
<age>8</age>
<son>Seth</son>
</Family>
I would like to read that from my html page
You can use XSLT - language for transforming XML documents. Maybe this would fit your needs.
I have modified your provided XML a little bit, because I think it is not structured well. So if we have such document:
<?xml version="1.0"?>
<?xml-stylesheet href="bla.xsl" type="text/xsl" ?>
<family>
<person>
<role>Mom</role>
<name>Alison</name>
<age>44</age>
</person>
<person>
<role>Father</role>
<name>Ben</name>
<age>45</age>
</person>
<person>
<role>Son</role>
<name>Ian</name>
<age>8</age>
</person>
</family>
The XSLT file would look something like this:
<?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>
<h2>Family</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>Role</th>
<th>Name</th>
<th>Age</th>
</tr>
<xsl:for-each select="family/person">
<tr>
<td><xsl:value-of select="role"/></td>
<td><xsl:value-of select="name"/></td>
<td><xsl:value-of select="age"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
a) Simply linking your Xml file
You can link to your Xml file from a Html page by using Server Side Includes.
If your Webserver is configured to allow this feature (this is usually disabled for security reasons) all you need to do is to rename your Html page to .shtml and add the server side include command.
foo.shtml
<html>
<head/>
<body>
<!--#include file="bar.xml" -->
</body>
</html>
bar.xml
<?xml version="1.0"?>
<Family>
<Mom>Alison</Mom>
<age>44</age>
<son>Ian</son>
<age>8</age>
<son>Seth</son>
</Family>
This will show the text Alison 44 Ian 8 Seth in your browser.
b) Rendering your Xml file as Html
If you want to render your complete Xml file as a Html page wenuxas has the correct answer for you.
c) Embedding your Xml file into your Html page
If your Xml document represents only a fragment of your final page Ajax may be what you are looking for.
If you just want to display the XML contents as they look in the file, you can search and replace all brackets (< becomes < and > becomes >), then paste the result in between <pre> and </pre> tags.
I would say the most common way is to use a server-side development platform such as ASP.NET to read the XML file and then format it into the page markup.
If there's a more direct way to include XML content in an HTML page, I'm not familiar with it.

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