xslt is not getting data from xml? - asp.net

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="#..OfferLetter.xslt"?>
<Doc>
<assembly>
<Heading>Offer Letter</Heading>
</assembly>
<RefNo>Ref No:0007</RefNo>
<Date></Date>
<to>To</to>
<name></name>
<city></city>
<dear>
<a>Dear Mr.</a>
<name></name>
</dear>
<p1>
<a1>
With reference to your application and the subsequent personal interview attended by you,
we are pleased to inform that you have been selected for employment in ..
(hereinafter referred to as “Company”).
We are delighted to make you the following offer for employment.
</a1>
</p1>
</Doc>
here my xslt code for that..
<?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="/">
<html>
<body>
<h2 style ="text-align: center;">Offer Letter</h2>
<h3 style="text-align:Right; margin-right: 110px;">Ref No:K070813</h3>
<h3 style="text-align:Right ; margin-right: 224px; ">Date:</h3>
<h3 style="text-align:Left; margin-left: 50px;">To</h3>
<h3 style="text-align:Left; margin-left: 50px;">MR.</h3>
<h3 style="text-align:Left; margin-left: 50px;">Hyderabad</h3>
<br></br>
<h3 style="text-align:Left; margin-left: 50px;">Dear Mr.</h3>
<xsl:for-each select="Doc/p1">
<h3 style="text-align:Left; margin-left: 50px;">
<xsl:value-of select="a1"/>
</h3>
</xsl:for-each>
</body>
</html>
here my TransformHRML() code
public static void TransformXML()
{
// Create a resolver with default credentials.
XmlUrlResolver resolver = new XmlUrlResolver();
resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
// transform the OfferLetter.xml file to HTML
XslTransform transform = new XslTransform();
// load up the stylesheetfile:
transform.Load(HttpContext.Current.Server.MapPath("OfferLetter.xslt"));
// perform the transformation
transform.Transform(#"..\OfferLetter.xml", #"..\OfferLetter.html", resolver);
// transform the OfferLetter.xml file to comma delimited format
// load up the stylesheet
transform.Transform(HttpContext.Current.Server.MapPath("OfferLetter.xslt"), #"..\OfferLetter.html",resolver);
}
please help me..

There are a bunch of close-tag issues, and the extraneous # in the xml file as picked up by Tim.
After tidying these up, your xslt works, but I would push you to use apply-templates and not for-each:
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="OfferLetter.xslt"?>
<Doc>
<assembly>
<Heading>Offer Letter</Heading>
</assembly>
<RefNo>Ref No:0007</RefNo>
<!--etc-->
<p1>
<a1>
With reference to your application and the subsequent , ...
</a1>
</p1>
<p1>
<a1>
Another Paragraph
</a1>
</p1>
</Doc>
With the 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:template match="/">
<html>
<body>
<!--Did you mean to hard code these fields? -->
<h2 style ="text-align: center;">
<xsl:value-of select="assembly/Heading"/>
</h2>
<h3 style="text-align:Right; margin-right: 110px;">
<xsl:value-of select="assembly/RefNo"/>
</h3>
<!--etc-->
<xsl:apply-templates select="Doc/p1">
</xsl:apply-templates>
</body>
</html>
</xsl:template>
<xsl:template match="p1">
<h3 style="text-align:Left; margin-left: 50px;">
<xsl:value-of select="a1"/>
</h3>
</xsl:template>
</xsl:stylesheet>

Related

How to display image using xslt and xml?

I have been trying to display image for quite sometimes now and some of the solutions in this website does not work for me...
This is my xslt code
<xsl:template match="/">
<div class="main">
<h2>Product Catalogue</h2>
<xsl:for-each select="productdetails/product">
<div class="box">
<img src="<xsl:value-of select="product_image"/>"> </img>
<xsl:value-of select="format-number(product_Price,'0.00')" />
<h3>
<xsl:value-of select="product_Name"/>
</h3>
RM<xsl:value-of select="format-number(product_Price,'0.00')" />
<br/>
<p style="font-size:9pt; font-style: italic;">
<xsl:value-of select="product_description"/>
</p>
<br/>
Add to Cart
</div>
</xsl:for-each>
</div>
</xsl:template>
Just so you know product_image in the xml is already the imagepath thats why I did not need to write the path in the xslt code.
In XML, a tag cannot contain another tag - so this is invalid code:
<img src="<xsl:value-of select="product_image"/>"> </img>
Use either:
<img>
<xsl:attribute name="src">
<xsl:value-of select="product_image"/>
</xsl:attribute>
</img>
or:
<img src="{product_image}"/>
To understand the 2nd syntax, read about Attribute Value Templates.

Using an xslt file to turn xml file into svg?

I need to make an xslt that turns my xml file into an svg.
The can't load the desired image, but it's basically a bar graph with a title at the top that says "Fall 2018 enrollment" and the height of each bar in the graph is based on the enrollment element in the xml file (so it's not hard coded).
I've been fiddling around with it a bit but I really don't know what to do.
This is the xml file:
<?xml version="1.0" encoding="UTF-8"?>
<courses>
<course number="341" credits="4.0">
<title>Data Structures</title>
<section number="01" delivery="Classroom">
<enrollment>15</enrollment>
<room>EA244</room>
<instructor>
<first>Nicole</first>
<last>Anderson</last>
</instructor>
</section>
<section number="02" delivery="Online">
<enrollment>10</enrollment>
<instructor>
<first>Nicole</first>
<last>Anderson</last>
</instructor>
<instructor>
<first>Chi-Cheng</first>
<last>Lin</last>
</instructor>
</section>
<section number="03" delivery="Classroom">
<enrollment>12</enrollment>
<room>SH102</room>
<instructor>
<first>Mark</first>
<last>Funk</last>
</instructor>
</section>
</course>
<course number="368" credits="4.0">
<title>Introduction to Bioinformatics</title>
<section number="01" delivery="Classroom">
<enrollment>9</enrollment>
<room>AT102</room>
<instructor>
<first>Chi-Cheng</first>
<last>Lin</last>
</instructor>
<instructor>
<first>Mingrui</first>
<last>Zhang</last>
</instructor>
</section>
</course>
<course number="375" credits="4.0">
<title>Computer Systems</title>
<section number="01" delivery="ITV">
<enrollment>18</enrollment>
<room>EA244</room>
<instructor>
<first>Chi-Cheng</first>
<last>Lin</last>
</instructor>
</section>
</course>
<course number="385" credits="3.0">
<title>Applied Database Management Systems</title>
<section number="01" delivery="Classroom">
<enrollment>26</enrollment>
<room>ST108</room>
<instructor>
<first>Nicole</first>
<last>Anderson</last>
</instructor>
</section>
</course>
<course number="413" credits="3.0">
<title>Advanced Networking</title>
<section number="01" delivery="Online">
<enrollment>10</enrollment>
<instructor>
<first>Chi-Cheng</first>
<last>Lin</last>
</instructor>
</section>
</course>
</courses>

This is my attempt at an 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/2000/svg">
<xsl:output indent="yes" cdata-section-elements="style"/>
<xsl:param name="width" select="40"/><!--width of bars-->
<xsl:param name="space" select="10"/><!--space between bars-->
<xsl:variable name="max-y" select="//enrollment[not(//enrollement > .)[1]"/>
<xsl:template match="courses">
<svg>
<defs>
<style type="text/css"><![CDATA[
g.bar text {
font-family: Arial;
text-anchor: middle;
fill: white;
}
g.bar rect {
fill: blue;
}
]]>
</style>
</defs>
<g transform="translate(10,10)">
<xsl:apply-templates select="course"/>
</g>
</svg>
</xsl:template>
<xsl:template match="course">
<xsl:variable name="prev-course" select="preceding-sibling::course "/>
<g class="course" id="course-{position()}" transform="translate({
count($prev-course/section) * ($width + $space)
+ count($prev-course) * $space
})">
<xsl:apply-templates select="section" />
</g>
</xsl:template>
<xsl:template match="section">
<xsl:variable name="prev-section" select="preceding-sibling::section "/>
<g class="section" id="section-{position()}" transform="translate({
count($prev-section/enrollment) * ($width + $space)
+ count($prev-section) * $space
})">
<xsl:apply-templates select="enrollment" />
</g>
</xsl:template>
<xsl:template match="enrollment">
<xsl:variable name="idx" select="count(preceding-sibling::enrollment)" />
<xsl:variable name="pos" select="$idx * ($width + $space)" />
<g class="bar">
<rect x="{$pos}" y="{$max-y - .}" height="{.}" width="{$width}" />
<text x="{$pos + $width div 2.0}" y="{$max-y - $space}">
<xsl:value-of select="."/>
</text>
</g>
</xsl:template>
</xsl:stylesheet>
The line <xsl:variable name="max-y" select="//enrollment[not(//enrollement > .)[1]"/> lacks a closing brackets, I guess you want <xsl:variable name="max-y" select="//enrollment[not(//enrollement > .)][1]"/>.
I would probably use
<xsl:variable name="max-y">
<xsl:for-each select="//enrollment">
<xsl:sort select="." data-type="number" order="descending"/>
<xsl:if test="position() = 1">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:variable>
however.

XSLT 1.0 Substring then select distinct

I am quite new to xslt, so any help will be much appreciated. Below is my sample xml file.
<DocumentElement>
<Records>
<date>2014-07-01 00:00</date>
</Records>
<Records>
<date>2014-08-03 00:00</date>
</Records>
<Records>
<date>2013-08-03 00:00</date>
</Records>
<DocumentElement>
What I need is just to select distinct years from the dates.
Currently I have the below xslt which brings duplicate years.
<?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:ms="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="years" select="DocumentElement/Records/date"/>
<ul>
<xsl:for-each select="$years">
<li>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="concat('?archive=',substring( ., 1, 4))"/>
</xsl:attribute>
<xsl:value-of select="substring( ., 1, 4)"/>
</xsl:element>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
Which gives me the results below:
<ul>
<li>
2014
</li>
<li>
2014
</li>
<li>
2013
</li>
</ul>
But my expected result should be
<ul>
<li>
2014
</li>
<li>
2013
</li>
</ul>
I tried the following below but I get empty output
<?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:ms="urn:schemas-microsoft-com:xslt">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="years" select="substring(DocumentElement/Records/date, 1, 4)"/>
<ul>
<xsl:for-each select="$years[not(.=preceding::*)]">
<li>
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="concat('?archive=',substring( ., 1, 4))"/>
</xsl:attribute>
<xsl:value-of select="substring( ., 1, 4)"/>
</xsl:element>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>
Any help will be much appreciated. thanks.
Muenchian grouping is much more effective way of grouping in XSLT1.0 than using preceding/following/preceding-sibling/following-sibling axis. Try 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" indent="yes"/>
<xsl:key name="Date" match="DocumentElement/Records/date" use="substring(.,1,4)"/>
<xsl:template match="/">
<ul>
<xsl:for-each select="DocumentElement/Records/date[generate-id() = generate-id(key('Date', substring(.,1,4))[1])]">
<li>
<a href="{concat('?archive=',substring(.,1,4))}">
<xsl:value-of select="substring( ., 1, 4)"/>
</a>
</li>
</xsl:for-each>
</ul>
</xsl:template>
</xsl:stylesheet>

XSLT enumerate each child element

I am trying to create a super generic XSLT that basically can only count on the table & row elements being there. I have the following sample XML I am trying to make an XSLT for:
<?xml version="1.0" encoding="UTF-8"?>
<table>
<row>
<id>5311</id>
<status>Active</status>
<id_vendor>Verizon</id_vendor>
<mobile_number>555123456</mobile_number>
</row>
<row>
<id>5312</id>
<status>Inactive</status>
<id_vendor>Sprint</id_vendor>
<mobile_number>555123457</mobile_number>
</row>
<row>
<id>5313</id>
<status>Active</status>
<id_vendor>ATT</id_vendor>
<mobile_number>555123458</mobile_number>
</row>
</table>
The problem is that I do not know what the fields are going to end up being (id, status, id_vendor, mobile_number, etc. are all subject to change.
I want to make pleasant to look at view such as:
<div style="background-color:#E3CA87;padding:.2em">
<div style="background-color:#F1E2BB;padding:.2em">
<div>id: x<div>
<div>status: active<div>
<div>id_vendor: Verizon<div>
<div>mobile_number: 555123456<div>
<div>
<div>
Here is what I have so far.. but I can't get the anonymous elements going right:
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<body style="background-color:#eee;font-size:12pt;font-family:Arial;">
<xsl:for-each select="table/row">
<div style="background-color:#eee;padding:.5em">
<xsl:for-each select="/*">
<div style="background-color:#E3CA87;padding:.2em;border: 1px solid black">
<xsl:for-each select="./*">
<div style="background-color:#F1E2BB;padding:.2em">
<xsl:value-of select ="name(./*)"/>:
<xsl:value-of select="*" />
</div>
</xsl:for-each>
</div>
</xsl:for-each>
</div>
</xsl:for-each>
</body>
</html>
Close... but it was actually a little differnt.. just figured it out for anyone that want's to know:
<?xml version="1.0" encoding="UTF-8"?>
<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<body style="background-color:#eee;font-size:12pt;font-family:Arial;">
<xsl:for-each select="table/row">
<div style="background-color:#eee;padding:.5em">
<xsl:for-each select=".">
<div style="background-color:#E3CA87;padding:.2em;border: 1px solid black">
<xsl:for-each select=".">
<xsl:for-each select="./*">
<div style="background-color:#F1E2BB;padding:.2em">
<xsl:value-of select="concat(local-name(.), ': ', .)" />
</div>
</xsl:for-each>
</xsl:for-each>
</div>
</xsl:for-each>
</div>
</xsl:for-each>
</body>
</html>
Use relative paths e.g. <xsl:for-each select="*"> instead of <xsl:for-each select="/*">. Then I think you want to drop the inner for-each and simply replace it with
<div style="background-color:#F1E2BB;padding:.2em">
<xsl:value-of select="concat(local-name(), ': ', .)" />
</div>

CSS style and XSLT?

If I select a DIV tag in a XHTML file with XSLT, like //*[#id='background'] How do I add a style, like a background color or other CSS styles like borders to the DIV? And if I have a list inside the DIV ID=background, how can I style the list, like removing the bullets? :)
This is really easy with XSLT. For instance, your input is:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title></title>
</head>
<body>
<div id="background">
<ul style="list-style-type: bullet">
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>
</body>
</html>
You can use the identity transform to copy the input XML as is, and override the nodes of interest:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:x="http://www.w3.org/1999/xhtml"
exclude-result-prefixes="x">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*" />
</xsl:copy>
</xsl:template>
<xsl:template match="x:div[#id='background']">
<xsl:copy>
<xsl:attribute name="style">
<xsl:text>border-style:solid;border-width:medium</xsl:text>
</xsl:attribute>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="x:ul[ancestor::*
[name()='div' and #id='background']]/#style">
<xsl:attribute name="style">
<xsl:text>list-style-type: none</xsl:text>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
The output will be:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title></title>
</head>
<body>
<div style="border-style:solid;border-width:medium" id="background">
<ul style="list-style-type: none">
<li>Coffee</li>
<li>Tea</li>
<li>Milk</li>
</ul>
</div>
</body>
</html>

Resources