First use of XSLT: page shows blank - html

I am trying my hand at XSLT using this page as a guide:
http://www.w3schools.com/xml/xml_xsl.asp
I basically tried to modify the given XSL information to suit my tags, which happen to be in the form of a sitemap. However, when i apply the XSL style to my XML page, it shows as blank! Clearly i am missing/forgetting or not seeing something. Please help.
My XML (snippet only):
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="style.xsl" ?>
<!-- sitemap-generator-url="http://www.auditmypc.com/free-sitemap-generator.asp" -->
<!-- This sitemap was created using the free tool found here: http://www.auditmypc.com/free-sitemap-generator.asp -->
<!-- Audit My PC also offers free security tools to help keep you safe during internet travels -->
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"
>
<url>
<loc>http://www.site.com/</loc>
<lastmod>2014-03-17T13:30:25-05:00</lastmod>
</url>
<url>
<loc>http://www.site.com/index.php?format=feed&type=rss</loc>
<lastmod>2014-03-17T13:28:20-05:00</lastmod>
</url>
</urlset>
My XSL:
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="urlset/url">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold"><xsl:value-of select="loc"/></span>
</div>
<div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
<span>Last Modified:<xsl:value-of select="lastmod"/></span>
</div>
</xsl:for-each>
</body>
</html>
Thanks for the help!

The urlset element and its descendants in your example XML document are all in the http://www.sitemaps.org/schemas/sitemap/0.9 namespace, so in order to match them with XPath expressions you must bind a prefix to that namespace and use it consistently:
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sm="http://www.sitemaps.org/schemas/sitemap/0.9">
<body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE">
<xsl:for-each select="sm:urlset/sm:url">
<div style="background-color:teal;color:white;padding:4px">
<span style="font-weight:bold"><xsl:value-of select="sm:loc"/></span>
</div>
<div style="margin-left:20px;margin-bottom:1em;font-size:10pt">
<span>Last Modified:<xsl:value-of select="sm:lastmod"/></span>
</div>
</xsl:for-each>
</body>
</html>
In XSLT/XPath 1.0, unprefixed element names always mean elements in no namespace, and prefixed names take the namespace bindings from the stylesheet, not from the input XML.
As an aside, if you're writing XSLT to be interpreted on the client side by browsers then you will be restricted to XSLT 1.0, so I suggest you find a good 1.0-specific tutorial and reference guide. The material on w3schools isn't always clear about what version of XSLT/XPath it refers to and you'll get frustrated if you keep trying things that don't work, only to find they're 2.0-only constructs...

Remember, XPath (and therefore XSLT) is namespace-aware, but (in the 1.0 version of these standards at least) does not have the concept of default namespace (xmlns=) assignment. If you want to select namespaced nodes, your XPath must use explicit prefixes bound to the correct namespaces.

Related

How to keep XSLT from introducing whitespaces in HTML output

I am generating HTML from XML sources using XSLT. The HTML shows a lot of whitespace that was not in the original XML files. Normally this is not a problem as the browser will ignore the extra whitespace characters. But I am developing an application that relies on correct positioning of the text cursor inside the HTML page. The added whitespaces do mess up the offsets, making it impossible to reliably position the cursor inside an element.
My question: how can I get my XSLT to not introduce any additional whitespaces in text nodes? I am using <xsl:strip-space elements="*"/> but that does not keep the processor from introducing lots of whitespace. It looks like some pretty-printing processing is applied to the HTML and I have no idea where this comes from. I am currently using Saxon PE 9.9.1.7
[Edit]
I created a simple example that shows the same strange behaviour. First the XML:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<p>This is a long sentence. Trying to reproduce a whitespace handling problem with XSLT. This manual describes the spacecraft, safety aspects, usage and maintenance procedures. Make sure the manual is available to anyone who will be using the product.</p>
</root>
Here is the simplified XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="root">
<xsl:text disable-output-escaping="yes"><!DOCTYPE html>
</xsl:text>
<html>
<head>
<title>Test</title>
</head>
<body>
<xsl:apply-templates select="*"/>
<script src="cursor.js"></script>
</body>
</html>
</xsl:template>
<xsl:template match="p">
<p contenteditable="true" id="p1" onclick="show_position()">
<xsl:value-of select="."/>
</p>
</xsl:template>
</xsl:stylesheet>
The JavaScript file to show the current cursor position:
function show_position( )
{
alert('position: ' + document.getSelection().anchorOffset );
}
The HTML that is generated by the XSLT looks like this (shown in oXygen):
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
</head>
<body>
<p contenteditable="true" id="p1" onclick="show_position()">This is a long sentence. Trying to reproduce a whitespace handling problem with XSLT.
This manual describes the spacecraft, safety aspects, usage and maintenance procedures.
Make sure the manual is available to anyone who will be using the product.</p><script src="cursor.js"></script></body>
</html>
Viewing the HTML in a browser makes all the extra whitespaces collapse into a single space, as expected. Clicking inside the paragraph shows the current offset from the start of the paragraph. Clicking immediately before 'This manual' shows position 86. Clicking one character to the right shows position 96. The same extra whitespace is introduced in the sentence starting with 'Make sure'.
I tried with Chrome and Safari - both show identical results. It does not seem to be a browser problem, but an issue with HTML generation by the XSLT processor. I have tried other Saxon versions but the resulting HTML is always the same.
Any further info on how to prevent these extra whitespace characters in my HTML output would be highly appreciated.
The default for output method="html" is indent="yes", I think, so you could certainly explicitly set indent="no" on your xsl:output declaration.
Additionally, as you say you use Saxon PE 9.9, you have access to XSLT 3 features like suppress-indentation="p" and/or Saxon PE/EE specific settings to use a very high setting for the normal line length, check the documentation for e.g. saxon:line-length or similar.

Get XML atribute using XSLT for a href on HTML

I have come across this problem while doing a home project and I honestly do not know how to solve it.
The goal is, using XSLT, get a certain attribute from my XML and add it to href.
<Video videoID="v0001" imageLink="IMG/VIDEO_IMG/v0001_img.jpg"/>
Then, by applying the XSLT, that looks kinda like this:
<xsl:template match="/">
<xsl:for-each select="Video"/>
<a href="X">
<img src="Y"/>
</a>
</xsl:template>
where X is the imageLink from the XML and Y is gonna be the local link to the XHTML page of that single video.
<!--The goal is getting something like this after using XSLT-->
<a href="VIDEOS/video_v0001.xhtml">
<img class="User" src="../IMG/VIDEO_IMG/v0001_img.png" alt="VideoImage"/>
</a>
Assume that your XML input is:
<?xml version="1.0" encoding="UTF-8"?>
<Videos>
<Video videoID="v0001" imageLink="IMG/VIDEO_IMG/v0001_img.jpg"/>
<Video videoID="v0002" imageLink="IMG/VIDEO_IMG/v0002_img.jpg"/>
</Videos>
Then the XSLT script performing your task can be:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xhtml" doctype-public="-//W3C//DTD XHTML 1.1//EN"
doctype-system= "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
encoding="UTF-8" indent="yes" />
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="Videos/Video">
<a href="VIDEOS/video_{#videoID}.xhtml">
<img class="User" src="../{substring-before(#imageLink, '.')}.png"
alt="VideoImage"/>
</a>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:transform>
As you can see, there should be 2 Attribute Value Templates ({...}),
one drawing the content from source videoID attribute and the other -
from imageLink.
In the second case the content to be copied is limited to the part
before the dot, because in this case file name extension is different.
Note that I used method="xhtml" and both doctype attributes for XHTML
page. Maybe in your case they should be different.
For a working example see http://xsltransform.net/jxWYjVH/1
To get a full HTML page, add <head> tag and other HTML stuff, according
to your needs, e.g. a stylesheet for User class.

XML to XSL transformation

I am new to XML. I am trying to convert the following XMl file
<?xml version="1.0"?>
<parent original_id="OI123" id="I123">
<custompanel panel="cp"></custompanel>
</parent>
into the following HTML
<html>
<body><div xmlAttribute="{"original-id":"OI123","id":"I123"}">
<p xmlAttribute={"panel":"cp"}/>
</div>
</body>
</html>
XML tag <parent> should be converted to <div> and <custompanel> should be converted to <p> tag.
I have read the XSTL documentation from W3CSchool but still I am not exactly sure how to approach the problem.Can anyone help me with it?
The custom attribute needs to be stored in xmlAttribute as JSONObject.
After a quick research of the correct syntax I came up with this.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output
method="xml"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
indent="yes"
encoding="utf-8" />
<xsl:template match="parent">
<html>
<body>
<div xmlAttribute="{{'original-id':'{#original_id}','id':'{#id}'}}">
<xsl:apply-templates />
</div>
</body>
</html>
</xsl:template>
<xsl:template match="custompanel">
<p xmlAttribute="{{'panel':'{#panel}'}}" />
</xsl:template>
</xsl:stylesheet>
The tricky part is espacing the {} for the JSON, which we build ourselves. You need two curly braces {{ to have a literal one. Also you need to use single quotes ' inside the attributes as double quotes would be escaped to ". You can access attributes with the #foo selector, but now you need to use actual {} to make the processor recognize it should do something.
I guess that your actual file has more than one <parent>. In that case you need to have a root element around it, and you need to adjust the XSLT. Add another <xsl:template match="/"> and move the HTML frame there.

HTML Help, need easy way to change text on my site

i am making a website that will feature many articles that will always be changing, i am trying to find a way to quickly change the text in these articles as i am the only person who knows the code in the company.
I was thinking of having a text document or something that has the articles text and when it gets changed so does the text on the site.I just dont know how to implement this.
sorry if its hard to understand what i mean, im not too familiar with sleep these days.
You don't need any dynamic server code like the other answers are suggesting. Either a "static site generator" (there are uncountably many, but that should give you something to Google if my main answer doesn't satisfy you) or a client-side scripting.
XSLT was designed for this exact problem. It can be run client-side or server-side with xsltproc (for compatibility with dumb clients). XSLT 1.0 is well-supported by all common browsers, though if you need EXSLT extensions in IE you had to add shims. Note that Webkit-based browsers can't do XSLT on file:// URLs, either set up a local HTTP server or use Firefox.
I have a minimal example site set up here that includes multiple files in
one page: https://o11c.github.io/foo-test/foo-root.xml
foo-style.xml:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/index">
<html>
<body>
<h2>Merge test</h2>
<table border="1">
<tr>
<th>Attr</th>
<th>Value</th>
</tr>
<xsl:apply-templates select="document(include/#name)"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="root">
<xsl:for-each select="foo">
<tr>
<td><xsl:value-of select="#x"/></td>
<td><xsl:value-of select="text()"/></td>
</tr>
</xsl:for-each>
</xsl:template>
<xsl:template name="identity">
<xsl:copy>
<xsl:for-each select="node()|#*">
<xsl:call-template name="identity"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
foo-root.xml:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="foo-style.xslt"?>
<index>
<include name="foo-1.xml"/>
<include name="foo-2.xml"/>
</index>
foo-1.xml:
<?xml version="1.0"?>
<root>
<foo x="a">aa</foo>
<foo x="b">bb</foo>
<foo x="c">cc</foo>
</root>
foo-2.xml:
<?xml version="1.0"?>
<root>
<foo x="d">dd</foo>
<foo x="e">ee</foo>
<foo x="f">ff</foo>
</root>
Further resources:
XSLT 1.0 spec
XPath 1.0 spec - in particular the function reference
EXSLT extensions - node-set in particular is very useful.
xsltproc webpage
You could use wordpress, if you are building the site from scratch and not adding to an existing one. This will allow you to edit articles in a user friendly interface that will allow you to style the text and will be easier for other people in the company to edit as well. It's very fast to set up.
Or you could just keep the written text in the HTML file itself, but this may make it harder to maintain and style, and those not technical savvy may not be able to edit it or will end up breaking it.
Well you might do this using php and Mysql
You can easily display save the articles in mysql and you could create a simple user interface for the people respnsible for editing the code to edit it too easy

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.