Below is the input xml :
<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="value-of.xsl"?>
<MemeberDetails>
<Employee>
<Name>Madhu</Name>
<Sex>Male</Sex>
<DOB>2/10/1982</DOB>
<Address>JP Nagar ,Bangalore</Address>
<MemberId>094631</MemberId>
<Designation>SSE</Designation>
<Department>SG</Department>
</Employee>
</MemeberDetails>
where, i am referring value-of.xsl file using HREF in above xml. and this file is residing in same folder.
Below is the value-of.xslt file:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="/">
<CGIEmployeeDetails>
<PersonalDetails>
<Name>
<xsl:value-of select="/MemeberDetails/Employee/Name"/>
</Name>
<Gender>
<xsl:value-of select="/MemeberDetails/Employee/Sex"/>
</Gender>
<ResidentialAddress>
<xsl:value-of select="/MemeberDetails/Employee/Address"/>
</ResidentialAddress>
</PersonalDetails>
<WorkingDetails>
<PSAID>
<xsl:value-of select="//MemberId"/>
</PSAID>
<Designation>
<xsl:value-of select="/MemeberDetails/Employee/Designation"/>
</Designation>
<Department>
<xsl:value-of select="/MemeberDetails/Employee/Department"/>
</Department>
</WorkingDetails>
</CGIEmployeeDetails>
</xsl:template>
</xsl:stylesheet>
When i run above xml in browser , the output will result as text but not as XML .
If i use editor like Oxygen and transform the same xml file , the output will be XML.
I am not getting why browser is failing to transform a XML output ?
Is there anything to do with browser ?
In browsers, the "XML format" view is mostly a stylesheet adding syntax highlighting and Emacscript event handlers (show and hide chlids nodes, etc.).
So, when the document has a XSLT stylesheet PI, browsers don't run that "XML format" stylesheet but they try to render the transformation result. This intent is not the same for each browser. Only one thing is guaranteed: if it's proper XHTML or HTML, is render as is.
If the transformation result is not proper XHTML nor HTML (plain text, other XML vocabulary), the render mechanism varies from one to another: i.e Chrome is the only one showing nothing for unknown XML vocabulary, others render this as HTML anyway (rendering only text).
Are you using internet explorer? That is the only browser I know of that would completely ignore your XSL stylesheet
#Alejandro provided a good explanation.
Using IE, you can see the result of the XSLT transformation by right-clicking on the IE window and selecting "View Source"
Related
this is an empty xml document for which i am generating a response
<?xml version="1.0"?>
<EmptyResult xmlns="http://www.tandberg.com/XML/CUIL/2.0" product="TANDBERG Codec" version="TC7.1.1.168aadf" apiVersion="2"/>
this is the code for response
<?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="/">
<xsl:apply-templates select="//objects"/>
</xsl:template>
<xsl:template match="objects">
</xsl:template>
</xsl:stylesheet>
Your problem isn't directly XSLT related, but a question of your XSLT processor. Depending on what you use (Java, .net, PHP, Ruby etc.) you get different error messages when your output doesn't yield a result.
There are several steps you can take:
handle the error in your code. After all your stylesheet doesn't do its job
fix the stylesheet to include an output for an <EmptyResult tag too
While you are on it: select=// is a performance killer for large outputs
Hope that helps
I have to transform my input xml using XSLT.
It contains, CDATA and I need to extract elements from CDATA and then I have to rename the tag.
Below is my input xml :
<getArtifactContentResponse>
<return>
<![CDATA[
<metadata>
<overview>
<name>scannapp</name>
<developerId>developer702</developerId>
<stateId>2</stateId>
<serverURL>dddd</serverURL>
<id>cspapp1103</id>
<description>scann doc</description>
<hostingTypeId>1</hostingTypeId>
</overview>
</metadata>
]]>
</return>
</getArtifactContentResponse>
And the expected output is :
<?xml version="1.0" encoding="UTF-8"?>
<metadata >
<information>
<name>scannapp</name>
<developerId>developer702</developerId>
<stateId>2</stateId>
<serverURL>ddddd</serverURL>
<id>cspapp1103</id>
<description>scann doc</description>
<hostingTypeId>1</hostingTypeId>
</Information>
</metadata>
XSLT I am using is below :
<xsl:output method="xml" version="1.0" encoding="UTF-8" />
<xsl:template match="/">
<xsl:value-of select="//ns:getArtifactContentResponse/ns:return/text()" disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="overview">
<Information>
<xsl:apply-templates select="#* | node()" />
</Information>
</xsl:template>
With this I am able to exrtact the CDATA but it is not renaming the element 'overview' to 'Information' .
Transformed xml is below :
<?xml version="1.0" encoding="UTF-8"?>
<metadata>
<overview>
<name>scannapp</name>
<developerId>developer702</developerId>
<stateId>2</stateId>
<serverURL>dddddd</serverURL>
<id>cspapp1103</id>
<description>scann doc</description>
<hostingTypeId>1</hostingTypeId>
</overview>
</metadata>
Can someone tell me how I can rename the tag after extracting the CDATA?
I don't understand what I am missing here?
Thanks in Advance
There are no elements in your CDATA, there is only text. That's what CDATA means: "this stuff might look like markup, but I want it treated as text".
Turning text into elements is called parsing, so to extract the elements from the text in your CDATA you are going to have to parse it. There's no direct way to do this in XSLT until you get to XSLT 3.0 (which has a parse-xml() function). Some XSLT processors have an extension function to do it; in some (I believe) the exslt:node-set() function does this if you supply a string as input. With others, you can call out to your own Java or Javascript code to do the parsing. So it all becomes processor-dependent.
Another approach is to output the XML in your CDATA section using the disable-output-escaping trick, and then process it in a second transformation.
The best approach is to get rid of the CDATA tags before you start. They should never have been put there in the first place.
Say I have an XML file test.xml which contains (among other things) some MATHML:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="template.xsl"?>
<equation>
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<row>
<!-- Using a MATHML entity name here! -->
<mi>∑</mi>
</row>
</math>
</equation>
I would like to use a browsers XSLT engine to convert the test.xml into XHTML+MATHML and display it. My XSLT file template.xsl looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/equation">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
Here is an equation:
<xsl:copy-of select="."/>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
When I open test.xml in the browser it errors out stating that the entity ∑ is not declared. Obviously I would like the ∑ sign displayed as it should. When I use the numeric entity ∑ it works as expected, but looking up the numeric entities for each math symbol is a pain.
I tried playing the the <xsl:output> tag trying different document-types, such as doctype-system="http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd" but so far no luck.
XSLT requires well-formed XML as input, and a file that references an undeclared entity is not well-formed. If you're going to use MathML entity references in an XML document, you need to reference the DTD that contains their definitions.
I am using about a dozen XSLT files to provide a large number of output formats. At the moment the user has to know the extension of the file format being exported to e.g. RTF, HTML, TXT.
I would also like to use parameters to allow more options. If I can embed the metadata in the XSL file itself then I can pick up the details by scanning through the files.
Here is what I am thinking about. In this example the program would have to parse the comments for the required information.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Title: Export to Rich Text Format -->
<!-- Description: This Stylesheet converts to a Rich Text Format format which may be used in a word processor such as Word -->
<!-- FileFormat: RTF -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:param name="CompanyName"/> <!-- Format:String, Description: Company name to be inserted in the footer -->
<xsl:param name="DateDue"/> <!-- Format:Date-yyyy-mm-dd, Description: Date Due -->
<xsl:param name="IncludePicture">true</xsl:param><!-- Format:Boolean, Description: Do you want to include a graphical representation? -->
<xsl:template match="/">
<!-- Stuff -->
</xsl:template>
</xsl:stylesheet>
Are there any standards out there? Do I need to butcher more than one (Dublin Core with a smattering of XML Schema)?
P.S. the project this is being applied to is Argumentative.
Here is what I am thinking about. In
this example the program would have to
parse the comments for the required
information.
You don't need to code the metadata within comments.
Metadata can be specified as part of the XSLT stylesheet using ordinary XML markup -- as rich in structure and meaning as we need.
Here is an example how to do that:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:meta="my:meta">
<xsl:output method="text"/>
<meta:metadata>
<title>Title: Export to Rich Text Format </title>
<description>
This Stylesheet converts to a Rich Text
Format format which may be used in a word processor
such as Word
</description>
<fileFormat>RTF</fileFormat>
<parameters>
<parameter name="CompanyName" format="xs:string"
Description="Company name to be inserted in the footer"/>
<parameter name="DateDue" format="xs:date"
Description="Date Due"/>
<parameter name="IncludePicture" format="xs:boolean"
Description="Do you want to include a graphical representation?"/>
</parameters>
</meta:metadata>
<xsl:param name="CompanyName"/>
<xsl:param name="DateDue"/>
<xsl:param name="IncludePicture" select="true"/>
<xsl:variable name="vMetadata" select=
"document('')/*/meta:metadata"/>
<xsl:template match="/">
This is a demo how we can access and use the metadats.
Metadata --> Description:
"<xsl:copy-of select="$vMetadata/description"/>"
</xsl:template>
</xsl:stylesheet>
when this transformation is applied on any XML document (not used), the result is:
This is a demo how we can access and use the metadats.
Metadata --> Description:
"
This Stylesheet converts to a Rich Text
Format format which may be used in a word processor
such as Word
"
Do note:
Any element that is in a namespace (of course not the no-namespace and not the xsl namespace) can be specified at the global level of any xslt stylesheet.
Such elements can be accessed using the xslt function document().
There's an XSL that includes another XSL:
<xsl:include href="registered.xsl"/>
That included file has a list of nodes:
<g:registered>
<node1/>
<node2/>
</g:registered>
Documentation says that "the children of the <xsl:stylesheet> element in this document replace the element in the including document", so I would think that, given the include directive has worked, I can select g:registered nodes like if they always belonged to the inluding document:
select="document('')/xsi:schema/g:registered"
That returns an empty nodeset though.
However, this:
select="document('registered.xsl')/xsi:schema/g:registered"
does select what is required, but that, as I suppose, means opening the included file for the second time which doesn't seem nice to me.
So how do I select those includes without opening the file second time?
EDIT
Requested document structure:
Included document:
<?xml version='1.0' encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:g="http://www.sample.com/ns">
<g:registered-templates>
<SampleTemplate/>
<WrongTemplate/>
</g:registered-templates>
<xsl:include href="Sample Template.xsl" />
<xsl:include href="Wrong Template.xsl" />
</xsl:stylesheet>
Including document:
<?xml version='1.0' encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:g="http://www.sample.com/ns">
<xsl:output method="text"/>
<xsl:include href="Label Registration.xsl"/>
<!-- How do I refer to just loaded inclusion without directing engine to the file again? -->
<xsl:variable name="template-names" select="document('Label Registration.xsl')/xsl:stylesheet/g:registered-templates"/>
<xsl:template match="Job">
<xsl:for-each select="WorkItem">
<xsl:apply-templates select="$template-names/*[local-name()=current()/#name]">
<xsl:with-param name="context" select="." />
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Selecting into your variable template-names queries the transformation source document - not your included stylesheet.
If you want to refer to g:registered-templates you have to point to the file like a second source document.
EDIT
I'm not really sure. but it looks like you want to create an element according to the attribute value.
In that case this post will be interesting for you.
<xsl:for-each select="WorkItem">
<xsl:element name="{Type}" >
<xsl:value-of select="current()/#name"/>
</xsl:element>
</xsl:for-each>
Ok, my understanding was wrong.
The document('') function opens the file anyway, so it has no advantages, performance-wise, over document('registered.xsl'). And since it queries the file, not the now-modified DOM model of current document, the result does not include my includes.
And it is not possible to query DOM model of the transformation template itself, as far as I'm concerned.