I want to embbed a XSLT transformation into an <iframe>. Here are my 2 files:
simple.html:
<!DOCTYPE html>
<html>
<body>
<iframe>
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="simple.xsl"?>
<text>
Hello World
</text>
</iframe>
</body>
</html>
simple.xsl:
<?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>
Content: <xsl:value-of select="." />
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Obviously, it doesn't work.
If I put the XML code of the <iframe> into a file named simple.xml and reference it like that <iframe src="simple.xml">, it works well but I don't want to have a separate XML file.
The reason is because the XML code will be provided by the user and I don't want to store it temporarily on my server just so I can reference it in the <iframe>, I want to do all client-side.
Is it possible to do that? If so, how can I do?
Thank you for your help.
Related
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.
I am wondering if there is possible such situation where I can place inline xml linked with xsl into the body of html, like:
<html>
<body>
text
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?xml-stylesheet type="text/xsl" href="articles.xsl"?>
<articles>
<article title="title"/>
</articles>
text
</body>
</html>
As Michael Kay suggested, you can embed the XML in XHTML and apply the stylesheet to the entire document. Then you can apply an XSL transformation to the entire document, applying the identity transform to all HTML elements and specific templates to the embedded non-HTML elements.
Here is an example:
Input XHTML
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ie8fix.xsl"?>
<!DOCTYPE html SYSTEM "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test</title>
</head>
<body>
text
<articles xmlns="">
<article title="title"/>
</articles>
text
</body>
</html>
XSLT
<?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">
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="articles">
<div class="articles">
<h1>articles</h1>
<xsl:apply-templates select="article" mode="transform"/>
</div>
</xsl:template>
<xsl:template match="article" mode="transform">
<article><!-- HTML5 article element -->
<h2><xsl:value-of select="#title"/></h2>
<xsl:apply-templates select="node()" mode="transform"/>
</article>
</xsl:template>
</xsl:stylesheet>
Output XHTML
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ie8fix.xsl"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>test</title>
</head>
<body>
text
<div class="articles">
<h1>articles</h1>
<article>
<h2>title</h2>
</article>
</div>
text
</body>
</html>
Another option would be to transform the XML after loading the page using JavaScript and XSLTProcessor.
See section 2.4 of
http://www.w3.org/TR/2012/NOTE-html-xml-tf-report-20120209/
The two approaches suggested there are
(a) Put the XML inside a script element
(b) Use XHTML.
Direct nesting of XML inside the HTML as in your example is not advised because the HTML parser will treat the XML as bad HTML, and try to repair it.
I have to display an XML document using XSLT but I would like apply the <p> and <i> HTML tags from the original XML document. For example p tag from XML would create a new paragraph. What would be the best way to accomplish this?
XML and XSLT code posted below.
Edit: clarified the original question
<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="tour.xsl"?>
<cars>
<car>
<description>
<p><i>There is some text here</i> There is some more text here</p>
<p>This should be another paragraph</p>
<p>This is yet another paragraph</p>
</description>
</car>
</cars>
<?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" version="4.0"/>
<xsl:template match="/">
<html>
<head>
<title>Title</title>
</head>
<body>
<xsl:value-of select="car"/><p/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>`
your actual question can be answered with a stylesheet like this, which uses apply-templates
<?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" version="4.0" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>Title</title>
</head>
<body>
<xsl:apply-templates select="/cars/car/description/*"/>
<p/>
</body>
</html>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
However, if you have multiple cars you probably want to have some headlines. Then a stylesheet like this may point towards that goal:
<?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" version="4.0" indent="yes"/>
<xsl:template match="/">
<html>
<head>
<title>Title</title>
</head>
<body>
<xsl:apply-templates select="/cars/car/*"/>
<p/>
</body>
</html>
</xsl:template>
<xsl:template match="description">
<h1>Subtitle</h1>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
You can extend your template to copy over the p elements like 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="html" version="4.0"/>
<xsl:template match="/">
<html>
<head>
<title>Title</title>
</head>
<body>
<xsl:for-each select="/cars/car">
<xsl:for-each select="description/p">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Given your XML input, the above XSLT will produce this output:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Title</title>
</head>
<body>
<p><i>There is some text here</i> There is some more text here
</p>
<p>This should be another paragraph</p>
<p>This is yet another paragraph</p>
</body>
</html>
Update:
I am trying to run in komodo's built in browser and ie.
You'd have to research komodo's XSLT capabilities. Also, be aware of challenges running XSLT in the browser; better to run on the server or in batch mode and only use the browser to display the results.
That said, the following XML file will open in IE 11 and be styled per the above XSLT sheet (named tour.xml and located in the same directory as the XML file):
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type='text/xsl' href='tour.xsl'?>
<cars>
<car>
<description>
<p><i>There is some text here</i> There is some more text here</p>
<p>This should be another paragraph</p>
<p>This is yet another paragraph</p>
</description>
</car>
</cars>
Here's a screenshot of the output in IE 11:
Update 2
I tried the template solution but it still returns unformatted text in
one line.
If IE 11 is given an XML file without a xml-stylesheet PI,
<?xml-stylesheet type='text/xsl' href='tour.xsl'?>
then it will display the XML in an outline form.
If IE 11 is given an XML file with a xml-stylesheet PI and it can find the XSLT file specified, it will apply the XSLT and display the results in the browser. This result can be seen in the above screenshot (and is your desired result).
If IE 11 is given an XML file with a xml-stylesheet PI and it cannot find the XSLT file specified, it will display unformatted text in one line as you describe.
Therefore, focus the search for your problem on the location and name of the XSLT file. Here is what happens when I intentionally force such behavior by renaming the XSLT file,
<?xml-stylesheet type='text/xsl' href='tour_CANNOT_FIND.xsl'?>
so that it cannot be found:
Note: Press F-12 to reveal the console.
Then, if you click on the "Allow blocked content" button:
You see the diagnostic message that tour_CANNOT_FIND.xsl cannot be found. If you resolve the problem of IE not finding your XSLT file, you should then see the formatted results of your XSLT file in the browser.
I don't know too much about XSL but have managed to format XML coming from 3rd party web services using XSL without too much trouble. But the other day, a site that used to work stopped working. I discovered that they made a tiny change to the XML returned by the web service. This is what used to work (greatly simplified):
Update: I see the problem now, but I don't have a solution. The problem is with xsl:if test="#xsi:type='r0:CreditTx'". Change every "r0" to "s0" in the XSL, and it does not work.
I have replaced my original code with a working example:
XML:
<?xml version="1.0" encoding="unicode"?>
<MyResp xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:r0="http://www.foo.com/2.1/schema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<r0:creditVendReceipt receiptNo="1234567890">
<r0:transactions>
<r0:tx xsi:type="r0:CreditTx">
<r0:amt value="100" />
</r0:tx>
</r0:transactions>
</r0:creditVendReceipt>
</MyResp>
XSL:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:r0="http://www.foo.com/2.1/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:template match="/">
<html>
<head>
</head>
<body >
<xsl:for-each select="MyResp/r0:creditVendReceipt/r0:transactions/r0:tx">
<xsl:if test="#xsi:type='r0:CreditTx'">
<xsl:value-of select="r0:amt/#value"/>
</xsl:if>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Desired HTML:
<html xmlns:r0="http://www.foo.com/2.1/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<head>
<META http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
100
</body>
</html>
The problem came when the web service changed the xmlns' short name "a" to "a0" (it now sends xmlns:a0="http://mysite.com/webservice/1.0/schema"); the namespace and everything else is the same. I have to change "a" to "a0" in the XSL for it to work (i.e. "GetInfoResp/a0:userName"). The problem is that the short name sent by the service changes from time to time. (In the real app there are a lot of name spaces, and the short names are even changing between the various requests.)
I thought the short name was just to make the XML shorter and easier to read, and that the actual name isn't significant (betwen the XML and the XSL; within the XSL obviously it has to match).
Can I get the XSL to ignore the short name in the XML, and just use its own short name?
Sorry if this was answered before; I looked thru the other questions and didn't see this specific issue.
The "short name" is called a namespace prefix -- and you don't have to change the namespace prefix in the transformation -- in fact it may be completely different from any prefix that could be used in the XML document.
This transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xYz="http://mysite.com/webservice/1.0/schema"
exclude-result-prefixes="xYz">
<xsl:template match="/">
<html>
<body >
<xsl:value-of select="GetInfoResp/xYz:userName"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
produces exactly the same result as this transformation:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a0="http://mysite.com/webservice/1.0/schema"
exclude-result-prefixes="a0">
<xsl:template match="/">
<html>
<body >
<xsl:value-of select="GetInfoResp/a0:userName"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Both transformations, when applied on this XML document (what is provided in the question is severely malformed and had to be corrected):
<GetInfoResp xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a0="http://mysite.com/webservice/1.0/schema">
<a0:userName>Joe</a0:userName>
</GetInfoResp>
produce the same result:
<html>
<body>Joe</body>
</html>
Lesson to learn:
What matters is the namespace, not the prefix used to shorthand it.
What am I doing wrong? It shows up as a blank page. I don't know a whole lot of xslt so I'm just testing it right now. If I can't get this to show up though then I can't really test how it works.
My XML
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="q3.xsl"?>
<expenseReport>
<companyInfo>
<name>John Doe</name>
<email>JDoe#company.com</email>
<empNum>1</empNum>
<companyCode>10010011</companyCode>
</companyInfo>
</expenseReport>
xslt
<?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>Test</h1>
<xsl:value-of select="expenseReport/companyInfo/name"/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
I can't even get that <h1> to show up, what's going on?
Please use --allow-file-access-from-files if you are trying to view local files from Chrome. They are very strict with local file access so do not rely on this option when you deploy your site. Only use it for development! I just checked it with version 14.0.385.202 and it worked.
Other than this your .xslt is just fine!