I'm trying to apply an xlst transformation using the following file. This is very basic, but I wanted to build off of this when I get it working correctly.
<?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:template match="/">
<div>
<h2>Station Inventory</h2>
<hr/>
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="StationInventory">
<h5><xsl:value-of select="station-name" /></h5>
<xsl:apply-templates select="detector"/>
</xsl:template>
<xsl:template match="detector">
<span>
<xsl:value-of select="detector-name" />
</span>
<br/>
</xsl:template>
</xsl:stylesheet>
Here is some xml I'm using for the source.
<StationInventoryList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.dummy-tmdd-address">
<StationInventory>
<station-id>9940</station-id>
<station-name>Zone 9940-SEB</station-name>
<station-travel-direction>SEB</station-travel-direction>
<detector-list>
<detector>
<detector-id>2910</detector-id>
<detector-name>1999 West Smith Exit SEB</detector-name>
</detector>
<detector>
<detector-id>9205</detector-id>
<detector-name>CR-155 Exit SEB</detector-name>
</detector>
<detector>
<detector-id>9710</detector-id>
<detector-name>Pt of View SEB</detector-name>
</detector>
</detector-list>
</StationInventory>
</StationInventoryList>
Any ideas what I'm doing wrong? The simple intent here is to make a list of station, then make a list of detectors at a station. This is a small piece of the XML. It would have multiple StationInventory elements.
I'm using the data as the source for an asp:xml control and the xslt file as the transformsource.
var service = new InternalService();
var result = service.StationInventory();
invXml.DocumentContent = result;
invXml.TransformSource = "StationInventory.xslt";
invXml.DataBind();
Any tips are of course appreciated. Have a terrific weekend.
Cheers,
~ck
Replace by
<?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" xmlns:st="http://www.dummy-tmdd-address">
<xsl:template match="/">
<div>
<h2>Station Inventory</h2>
<hr/>
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="st:StationInventory">
<h5><xsl:value-of select="st:station-name" /></h5>
<ul>
<xsl:apply-templates select="st:detector-list/st:detector"/>
</ul>
</xsl:template>
<xsl:template match="st:detector">
<li>
<xsl:value-of select="st:detector-name" />
</li>
</xsl:template>
</xsl:stylesheet>
because detector is child of detector-list not station inventory and there is a namespace
There are two obvious problems:
All elements in the XML document are in the default namespace, but in the XSLT code they are referenced as belonging to "no namespace".
The element <StationInventory> doesn't have any <detector> children.
Solution:
In the XSLT stylesheet below the above two problems are corrected:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:d="http://www.dummy-tmdd-address">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<div>
<h2>Station Inventory</h2>
<hr/>
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="d:StationInventory">
<h5><xsl:value-of select="d:station-name" /></h5>
<xsl:apply-templates select="d:detector-list/d:detector"/>
</xsl:template>
<xsl:template match="d:detector">
<span>
<xsl:value-of select="d:detector-name" />
</span>
<br/>
</xsl:template>
</xsl:stylesheet>
The result now is a complete output, that most probably was wanted:
<div xmlns:d="http://www.dummy-tmdd-address">
<h2>Station Inventory</h2>
<hr />
<h5>Zone 9940-SEB</h5>
<span>1999 West Smith Exit SEB</span>
<br />
<span>CR-155 Exit SEB</span>
<br />
<span>Pt of View SEB</span>
<br />
</div>
Related
Here my Xml
<document>
<metadata>
<title>Sign in to my account</title>
</metadata>
<topic>
<conceptuldocument>
<legacybold> Hi hello world </legacybold>
</conceptuldocument>
</topic>
</document>
I only need the title which is under the metadata data tag
all I would need is <h1> sign in to my account</h1>
but i am getting out put html as
<h1>sign in to my account</h1>Hi hello world
here my xslt :
<?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="/">
<xsl:choose>
<xsl:when test="metadata">
<xsl:apply-templates select="metadata"/>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="metadata">
<h1>
<xsl:value-of select="title"/>
</h1>
</xsl:template>
</xsl:stylesheet>
C# :
using (StringWriter sw = new StringWriter())
{
transform.Transform(xmldocument.DocumentElement,null, sw);
string html = sw.ToString();
}
output image
xml image
Xslt file image
wondering if any one can help me point what am i missing here , very new to xslt its just been a day.
Simplest fix is to change your entry template to
<xsl:template match="/">
<xsl:apply-templates select="document/metadata"/>
</xsl:template>
Note that your xsl:choose around the xsl:apply-templates is a waste of space. If the element doesn't exist, xsl:apply-templates will do nothing.
I'm not very good at XSLT, so hopefully someone can help :)
I'm trying to convert an HTML template (called from C# code), replacing placeholders with data from an XML file.
The (simplified) HTML template looks like:
<html>
<body>
Dear $firstName $lastName,
</body>
</html>
The XML file looks like:
<inputXml>
<firstName>Joske</firstName>
<lastName>Vermeulen</lastName>
</inputXml>
And the XSLT I came up with so far looks like:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
version="1.0"
xmlns:s0="http://www.w3.org/1999/xhtml">
<xsl:output omit-xml-declaration="yes" method="text" version="1.0" />
<xsl:variable name="templateMessage" select="document('stream:///TemplateMessage')" />
<xsl:variable name="inputData" select="/" />
<xsl:template match="/">
<xsl:apply-templates select="$templateMessage/*/node()" />
</xsl:template>
<xsl:template match="*/*">
<xsl:value-of select="$inputData//*[name()=name(current())]"/>
</xsl:template>
</xsl:stylesheet>
For some reason the output of the transformation is just empty, because the last match is probably not correct. (If I omit the last match, I get the original HTML template as output).
Anyone sees what I did wrong?
Ok, found a solution.
The template has placeholders like this:
<html>
<body>
Dear <span class="placeholder">firstName</span> <span class="placeholder">lastName</span>,
</body>
</html>
And the XSLT looks like:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
version="1.0"
xmlns:s0="http://www.w3.org/1999/xhtml">
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" />
<!-- This is the XML data to use to replace the placeholders in the HTML template with -->
<xsl:variable name="inputData" select="document('stream:///InputData')" />
<xsl:variable name="placeholders">
<list>
<placeholder id="firstName" value="{$inputData/inputXml/firstName}" />
<placeholder id="lastName" value="{$inputData/inputXml/lastName}" />
</list>
</xsl:variable>
<!-- Take the HTML template -->
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Replace every placeholder in the HTML template with the value from the XML data defined by its XPATH -->
<xsl:template match="span[#class='placeholder']">
<xsl:variable name="this" select="node()"/>
<xsl:value-of select="msxsl:node-set($placeholders)/list/placeholder[#id = $this]/#value" />
</xsl:template>
</xsl:stylesheet>
For just simple replacing the $firtstname and $lastname from the xml file I tried something like this and it works. Let me know if something is not clear. Just sharing with you in case it helps.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
version="2.0">
<xsl:variable name="templateMessage" select="document('MyXmldata.xml')" />
<xsl:variable name="inputData" select="/" />
<xsl:template match="/">
<html>
<body>
<xsl:variable name="firstName" select="$templateMessage/inputXml/firstName" />
<xsl:variable name="lastName" select="$templateMessage/inputXml/lastName" />
<xsl:variable name="StringValue" select="node()" />
<xsl:variable name="StringValue1" select="replace($StringValue,'\$firstName',$firstName)" />
<xsl:variable name="StringValue2" select="replace($StringValue1,'\$lastName',$lastName)" />
</body>
</html>
</xsl:template>
May be this code can help you .
i am replacing 
 with br tag to show new line while transforming xml using xsl. i want to replace blank spaces to its according code that may   or something else at the same time.sample code is below. please suggest for me what should i do.
while xml file may be as ------------
<?xml version="1.0" encoding="iso-8859-1"?><?xml-stylesheet type="text/xsl"
href="task.xsl"?><Nodes><sNode><Word><![CDATA[1
2.............3............4............5
3]]></Word></sNode></Nodes>
since blank spaces ommitted automatically so here ........ represents blank spaces.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<table>
<xsl:for-each select="Nodes/sNode">
<tr>
<td>
<xsl:call-template name="replace-string-with-element">
<xsl:with-param name="text" select="Word"/>
<xsl:with-param name="replace" select="'
'"/>
<xsl:with-param name="with" select="'br'"/>
</xsl:call-template>
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
<xsl:template name="replace-string-with-element">
<xsl:param name="text"/>
<xsl:param name="replace"/>
<xsl:param name="with"/>
<xsl:choose>
<xsl:when test="contains($text,$replace)">
<xsl:value-of select="substring-before($text,$replace)"/>
<xsl:element name="{$with}"/>
<xsl:call-template name="replace-string-with-element">
<xsl:with-param name="text" select="substring-after($text,$replace)"/>
<xsl:with-param name="replace" select="$replace"/>
<xsl:with-param name="with" select="$with"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
You could use xsl:character-map as follows:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn xs">
<xsl:character-map name="replaceChars">
<xsl:output-character character="
" string="br"/>
</xsl:character-map>
<xsl:output method="xml" version="1.0" encoding="UTF-8" use-character-maps="replaceChars" indent="yes"/>
<!-- Implement your templates -->
</xsl:stylesheet>
It is even possible to save all characters in a xsl:character-map in an external XSLT and use <xsl:import href="characterFile.xslt" />
To implement this in your stylesheet use the following XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:character-map name="replaceChars">
<xsl:output-character character="
" string="br"/>
</xsl:character-map>
<xsl:output method="html" use-character-maps="replaceChars"/>
<xsl:template match="/">
<html>
<body>
<table>
<xsl:for-each select="Nodes/sNode">
<tr>
<td>
<xsl:value-of select="Word" />
</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
I have an XML like this:
<table name="tblcats">
<row>
<Id>1741</Id>
<Industry>Oil & Gas - Integrated</Industry>
<ParentId>1691</ParentId>
</row>
<row>
<Id>1690</Id>
<Industry>Commodities</Industry>
<ParentId>1691</ParentId>
</row>
<row>
<Id>1691</Id>
<Industry>Capital Goods</Industry>
<ParentId>0</ParentId>
</row>
</table>
I want to create a Treeview from this XML so that table is parent node and then nodes ParentId 0 is second parent and then child nodes with Parent Id greater than 0
Like this:
+Table
+Capital Goods
Commodities
Oil & Gas - Integrated
How can I do this? Please suggest
Regards,
Asif Hameed
A fairly simplistic approach would be to use the standard ASP.NET controls XmlDataSource and TreeView and use an XSLT transform file to transform the XML you have into something that the TreeView control likes.
So, assuming you have the XML above in a file called cats.xml, the ASP.NET page markup would look like:
<asp:XmlDataSource ID="CatsXml" runat="server" DataFile="~/cats.xml" TransformFile="~/cats.xslt"></asp:XmlDataSource>
<asp:TreeView ID="CatsTree" runat="server" DataSourceID="CatsXml">
<DataBindings><asp:TreeNodeBinding TextField="name" ValueField="id" /></DataBindings>
</asp:TreeView>
and the XSLT file (cats.xslt) would be:
<?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="xml" indent="yes"/>
<xsl:template match="table">
<table id="-1" name="Table">
<xsl:for-each select="/table/row[ParentId = 0]">
<industry>
<xsl:attribute name="id">
<xsl:value-of select="Id"/>
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="Industry"/>
</xsl:attribute>
<xsl:call-template name="industry-template">
<xsl:with-param name="pId" select="Id" />
</xsl:call-template>
</industry>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="industry-template">
<xsl:param name="pId" />
<xsl:for-each select="/table/row[ParentId = $pId]">
<industry>
<xsl:attribute name="id">
<xsl:value-of select="Id"/>
</xsl:attribute>
<xsl:attribute name="name">
<xsl:value-of select="Industry"/>
</xsl:attribute>
<xsl:call-template name="industry-template">
<xsl:with-param name="pId" select="Id" />
</xsl:call-template>
</industry>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Stuart.
I have some input XML which is
<collection>
<content>
<id>10</id>
<type>xx</type>
<title>xx</title>
<quicklink>xx</quicklink>
<teaser><p>xxx</p></teaser>
<root>
<thumb><img src="/xxx/xxx.jpg" /></thumb>
<link>http://www.foo.com</link>
</root>
<startDate></startDate>
<enddate></enddate>
<hyperlink>some text</hyperlink>
</content>
<content>
<id>10</id>
<type>xx</type>
<title>xx</title>
<quicklink>xx</quicklink>
<teaser><p>xxx</p></teaser>
<root>
<thumb><img src="/xxx/xxx.jpg" /></thumb>
<link>http://www.foo.com</link>
</root>
<startDate></startDate>
<enddate></enddate>
<hyperlink>some text</hyperlink>
</content>
<content>
<id>10</id>
<type>xx</type>
<title>xx</title>
<quicklink>xx</quicklink>
<teaser><p>xxx</p></teaser>
<root>
<thumb><img src="/xxx/xxx.jpg" /></thumb>
<link>http://www.foo.com</link>
</root>
<startDate></startDate>
<enddate></enddate>
<hyperlink>some text</hyperlink>
</content>
</collection>
XSLT written to format an unordered list as below
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<ul id="case-study-icons">
<xsl:for-each select="collection/content">
<li>
<a>
<xsl:attribute name="href">
<xsl:value-of select="Html/root/Link"/>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:value-of select="title"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="Html/root/thumb/img/#src"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="title"/>
</xsl:attribute>
<xsl:attribute name="width">92</xsl:attribute>
<xsl:attribute name="height">46</xsl:attribute>
</img>
</a>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
I would like to change this to have 3 image links inside one li and grounp every 3 item occurance into 3 image links groups wrapped withli`. So at the end of the transformation the HTML must look like below
<ul id="case-study-icons">
<li>
<img src="/foo.jpg" />
<img src="/foo.jpg" />
<img src="/foo.jpg" />
</li>
<li>
<img src="/foo.jpg" />
<img src="/foo.jpg" />
<img src="/foo.jpg" />
</li>
<li>
<img src="/foo.jpg" />
<img src="/foo.jpg" />
<img src="/foo.jpg" />
</li>
</ul>
I did try to do this myself using position() somehow my logic seems not working. Can someone please have a look? Many thanks in Advance..
Select every third Content element then start the li element, then within that select the three elements you need. It wasn't clear if your Content elements were siblings so I used following rather than following-sibling
<xsl:for-each select="(Collection/Content)[position() mod 3 = 1]">
<li>
<xsl:for-each select=".|following::Content[position() < 3]">
<a href="{Html/root/Link}" title="{Title}">
<img src="{Html/root/Thumb/img/#src}" alt="{Title}/>
</a>
</xsl:for-each>
</li>
</xsl:for-each>
Kindly David had pointed me at the right direction and I have managed to come to the correct transformation.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<ul id="case-study-icons">
<xsl:for-each select="(Collection/Content)[position() mod 3 = 1]">
<li style="width:100px; float:left;">
<xsl:for-each select=".|following-sibling::Content[position() < 3]">
<a>
<xsl:attribute name="href">
<xsl:value-of select="Html/root/Link"/>
</xsl:attribute>
<xsl:attribute name="title">
<xsl:value-of select="Title"/>
</xsl:attribute>
<img>
<xsl:attribute name="src">
<xsl:value-of select="Html/root/Thumb/img/#src"/>
</xsl:attribute>
<xsl:attribute name="alt">
<xsl:value-of select="Title"/>
</xsl:attribute>
<xsl:attribute name="width">92</xsl:attribute>
<xsl:attribute name="height">46</xsl:attribute>
</img>
</a>
</xsl:for-each>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
You might want to parameterise the number of items per group, rather than hard-code the 3. Additionally, it could be possibly be simplified, by firstly avoiding the need for nested xsl:for-each, and secondly by the use of Attribute Value Templates to write out attributes
Try this XSLT, for example
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="itemsperlist" select="3" />
<xsl:template match="/collection">
<ul id="case-study-icons">
<xsl:apply-templates select="content[(position() - 1) mod $itemsperlist = 0]" mode="first" />
</ul>
</xsl:template>
<xsl:template match="content" mode="first">
<li>
<xsl:apply-templates select=".|following-sibling::content[position() < $itemsperlist]" />
</li>
</xsl:template>
<xsl:template match="content">
<a href="{root/link}" title="{title}">
<img src="{root/thumb/img/#src}" alt="{title}" width="92" height="46" />
</a>
</xsl:template>
</xsl:stylesheet>
Note that this solution would work if you changed the 3 to a 1.