XML Atom Pagination - xslt

I've been searching the internet hard to get clues how to paginate XML atom feed, but not been successful. How can I display the pagination for navigation on a page? i.e. pages 1 2 ..9
<?xml version="1.0" encoding="utf-8" ?>
<feed xmlns:s="http://feed.example.com/services" xmlns="http://www.w3.org/2005/Atom">
<title type="text">org select - with 'Field' in name</title>
<id>http://feed.example.com/orga/srvic/name/Field</id>
<rights type="text">Copyright 2015</rights>
<updated>2010-05-09</updated>
<category term="Search" />
<logo>http://www.org.uk/orgcservices/docs/logo.jpg</logo>
<author>
<name>org select</name>
<uri>http://www.sampleorg.uk</uri>
<email>wbsrvcs#example.com</email>
</author>
<link rel="self" type="application/atom+xml" title="org select - Practices with 'Field' in name" href="http://feed.example.com/organisations/services/name/Field?apikey=12345" />
<link rel="first" type="application/atom+xml" title="first" length="1000" href="http://feed.example.com/organisations/services/name/Field?apikey=12345&page=1" />
<link rel="next" type="application/atom+xml" title="next" length="1000" href="http://feed.example.com/organisations/services/name/Field?apikey=12345&page=2" />
<link rel="last" type="application/atom+xml" title="last" length="1000" href="http://feed.example.com/organisations/services/name/Field?apikey=12345&page=9" />
<tracking xmlns="http://feed.example.com/services"><img style="border: 0; width: 1px; height: 1px;" alt="" src="http://webtrendsample.com/dfgfgh56dgd5/ddds.gif?fffuri=/organisations%2fservices%2fname%2fField&wt.js=no&wt.cg_n=feed"/></tracking>
<entry>
<id>http://feed.example.com/organisations/services/245645634</id>
<title type="text">Field Tree House</title>
<updated>2015-05-12T08:08:08Z</updated>
<link rel="self" title="Field Tree House Surgery" href="http://feed.example.com/organisations/services/24308?apikey=12345" />
<link rel="alternate" title="Field Tree House Surgery" href="http://www.org.uk/Srvcs/DR/Default.aspx?id=34343434" />
<content type="application/xml">
<s:organisationSummary>
<s:name>Field Tree House</s:name>
<s:odsCode>JD12345</s:odsCode>
<s:address>
<s:addressLine>Field Tree House</s:addressLine>
<s:addressLine>John Street</s:addressLine>
<s:addressLine>Lirkam</s:addressLine>
<s:addressLine>Stockion</s:addressLine>
<s:postcode>DWQ4 22GW</s:postcode>
</s:address>
<s:contact type="General">
<s:telephone>111 2223333444</s:telephone>
</s:contact>
</s:organisationSummary>
</content>
</entry>
<entry>
.
.
.
I don't have much experience with XML, so please bear with me. I have seen this: Pagination in feeds like ATOM and RSS? but this doesn't answer my query. Any ideas guys. I'd really appreciate it.
Thanks very much guys.

As you did not show what you tried, it is hard to figure out exactly what you want. If you want to compute the number of pages, given a page length, in an Atom feed, then it is simple arithmetics:
<xsl:variable name="page-length" select="10"/>
<xsl:template match="atom:feed">
<xsl:variable name="total" select="count(atom:entry)"/>
<xsl:choose>
<xsl:when test="$total eq 0">
<p>No entry.</p>
</xsl:when>
<xsl:otherwise>
<p>
<xsl:text>Pages: </xsl:text>
<xsl:value-of select="(($total - 1) idiv $page-length) + 1"/>
</p>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

Related

To assign dynamic URL's

I am new to XSLT Language, I am trying to write code that assigns dynamic URL's to Photo field in my list. My list contains FirstName, LastName and Photo fields of all employees and Photos are in a folder ("file://folder/subfolder/LastName, FirstName.jpg). Based on FirstName and LastName appropriate photo should be dynamically added to Photo Field.
Code I tried:
<xsl:template match="udt:Photo">
<xsl:for-each select="dnnGridItem">
<xsl:value-of select="udt:LastName" />
<xsl:value-of select="udt:FirstName" />
</xsl:for-each>
<img border="0" alt="delete">
<xsl:attribute name="src">
<xsl:text>file://folder/subfolder</xsl:text>
<xsl:value-of select="file://foilder/subfoilder/?{LastName}, {FirstName}.jpg" />
<xsl:text>.jpg</xsl:text>
</xsl:attribute>
</img>
</xsl:template>
Can any one help me with XSL code.
As you did not provide any input data I can suggest my example.
In my case required images are in path D:/images as below:
So to add images to HTML I am using next XSL file (photo.xsl) as below:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" />
<xsl:template match="/Photo">
<xsl:variable name="img.path" select="'file:///D:/images/'"/>
<html>
<body>
<xsl:for-each select="dnnGridItem">
<xsl:variable name="img.name" select="concat(LastName, ', ', FirstName)"/>
<h2>
<xsl:value-of select="$img.name"/>
</h2>
<img border="0" alt="delete">
<xsl:attribute name="src">
<xsl:value-of select="concat($img.path, $img.name, '.jpg')"/>
</xsl:attribute>
</img>
<br/>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Then to take LastName and FirstName dynamically add <?xml-stylesheet type="text/xsl" href="photo.xsl"?> to input XML file (input.xml) as below:
<?xml-stylesheet type="text/xsl" href="photo.xsl"?>
<Photo>
<dnnGridItem>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
</dnnGridItem>
<dnnGridItem>
<FirstName>Kate</FirstName>
<LastName>Johnson</LastName>
</dnnGridItem>
</Photo>
Result:
Transformed result:
<html>
<body>
<h2>Smith, John</h2>
<img border="0" alt="delete" src="file:///D:/images/Smith, John.jpg"><br>
<h2>Johnson, Kate</h2>
<img border="0" alt="delete" src="file:///D:/images/Johnson, Kate.jpg"><br>
</body>
</html>
Result when open XML(input.xml) file in browser:
NOTE! input.xml - in same folder with photo.xsl.
Hope it will help with your case.

xslt 1.0 - Trying to get nodes for a specific value

I've got an XML file that has many similarly named nodes but attributes within certain nodes are unique. I want to output into an HTML page only the nodes that fall under a certain attribute value.
Here is the xml:
<document>
<component>
<section>
<templateId value="temp_1" />
<entry>
<act>
<code displayName="temp_1:code_1" />
</act>
</entry>
<entry>
<act>
<code displayName="temp_1:code_2" />
</act>
</entry>
<entry>
<act>
<code displayName="temp_1:code_3" />
</act>
</entry>
</section>
<section>
<templateId value="temp_2" />
<entry>
<act>
<code displayName="temp_2:code_1" />
</act>
</entry>
<entry>
<act>
<code displayName="temp_2:code_2" />
</act>
</entry>
</section>
</component>
</document>
From this specific example, I want to only get the displayName value from the section that has the templateId value of temp_2. This is the XSL code that I'm using but it is getting everything, not just the section that I want. i know the first "when" is working because the right header (between the span tags) is displaying properly. It's just the for-each through the entries.
<xsl:tempalte match="/">
<xsl:choose>
<xsl:when test="//templateId/#value='temp_2'">
<div style="margin-bottom: 5px; padding: 5px; border-bottom: 1px solid #000000;">
<span style="font-weight: bold;">Template 2: </span>
<br />
<xsl:choose>
<xsl:when test="count(//section/entry) != 0">
<xsl:for-each select="//section/entry">
<xsl:choose>
<xsl:when test="position() = 1">
<xsl:value-of select="act/code/#displayName" />
</xsl:when>
<xsl:otherwise>
<br/>
<xsl:value-of select="act/code/#displayName" />
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
No codes to display
</xsl:otherwise>
</xsl:choose>
</div>
</xsl:when>
</xsl:choose>
</xsl:template>
It should display like so:
temp_2:code_1
<br>temp_2:code_2
Any help would be greatly appreciated.
I guess you want to completely restudy XSLT and its philosophy. Don't program it like it was BASIC. The basic pattern, at least for your case, is that an XSLT program is a collection of templates to handle matching elements. Instead of littering your code with if and choose, write templates with the proper matching conditions. Instead of BASIC's FOR I=1 TO 10, use <xsl:apply-templates/> to "iterate" over the children. Here's the basic idea:
<xsl:template match="/">
<html>
<xsl:apply-templates/>
</html>
</xsl:template>
<xsl:template match="templateId"/> <!-- skip templateID elements by default -->
<xsl:template match="templateId[#value='temp_2']">
<div style="margin-bottom: 5px; padding: 5px; border-bottom: 1px solid #000000;">
<span style="font-weight: bold;">Template 2: </span>
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="code">
<xsl:value-of select="#displayName"/>
<xsl:if test="position() != 1"><br/></xsl:if>
</xsl:template>
<xsl:template match="section[count(entry)=0]">
No codes to display
</xsl:template>
Why no template for act elements? Well, by default XSLT will provide you with a template which does a <xsl:apply-templates/>.
Based on your description it sounds like you only want the temp_2 values in your for-each.
That being the case you can just update your select to the following:
<xsl:for-each select="//section[templateId/#value = 'temp_2']/entry">
This says to grab any entry under section that has a templateId with an attribute of value that equals 'temp_2'.

XSLT Parsing error when using Umbraco GetMedia

I am trying to retrieve the url to an image using the GetMedia mediapicker.
The code below works fine:
<xsl:for-each select="umbraco.library:GetXmlNodeById(1123)/* [#isDoc]">
<article>
<img width="1822" height="600">
<xsl:attribute name="src">
<xsl:value-of select="umbraco.library:GetMedia(1139, 0)/umbracoFile" />
</xsl:attribute>
</img>
<div class="contents">
<h1>
<xsl:value-of select="bannerHeading1"/>
</h1>
</div>
</article>
</xsl:for-each>
However, if I replace the key line with this:
<xsl:value-of select="umbraco.library:GetMedia(bannerImage, 0)/umbracoFile" />
I get a parsing error with the exception being an OverflowException (Value was either too large or too small for an Int32), which suggests that it's not the 1139 that is being passed in.
Is there a way I can pass in the property I want? The value of "bannerImage" is 1139 as I want it to be?
Thanks for any help.
Further: This is the XML structure being returned by GetXMLNodeById:
<?xml version="1.0" encoding="utf-8" ?>
<HomepageBanner id="1141" parentID="1123" level="3" writerID="0" creatorID="0" nodeType="1124" template="1125" sortOrder="0" createDate="2013-08-12T15:53:48" updateDate="2013-08-12T15:54:18" nodeName="Members" urlName="members" writerName="admin" creatorName="admin" path="-1,1065,1123,1141" isDoc="">
<bannerImage>1139</bannerImage>
<bannerHeading1>Members Area</bannerHeading1>
<bannerHeading2>..the place for all your needs</bannerHeading2>
</HomepageBanner>
For anyone else trying to get an image from an item in a content folder, this is how I got it to work:
<xsl:for-each select="umbraco.library:GetXmlNodeById(1123)/* [#isDoc]">
<article>
<!-- Store the ID -->
<xsl:variable name="mediaId" select="bannerImage" />
<!-- Check the ID is numeric -->
<xsl:if test="number($mediaId) > 0">
<xsl:variable name="mediaNode" select="umbraco.library:GetMedia($mediaId, false())" />
<xsl:if test="string-length($mediaNode/umbracoFile) > 0">
<img src="{$mediaNode/umbracoFile}" width="1822" height="600" />
<div class="contents">
<h1>
<xsl:value-of select="bannerHeading1"/>
</h1>
</div>
</xsl:if>
</xsl:if>
</article>
</xsl:for-each>
You first need to check that the value is numeric and then, the bit that was failing me, you need to add the "/umbracoFile" part to your media node variable.
Thanks to the contributors who helped me in the right direction.

XSLT validation error javax.xml.transform.TransformerConfigurationException:

i'm having this error when i tried to validate my XSLT
javax.xml.transform.TransformerConfigurationException:
javax.xml.transform.TransformerException:
javax.xml.transform.TransformerException:
A node test that matches either NCName:* or QName was expected.
this is my XSLT
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="html" />
<xsl:template match="\Apps">
<html>
<head> <title>Apps List</title>
<link rel="StyleSheet" href="table_style.css" type="text/css"/>
<style type="text/css">
body {font-family: Helvetca;}
h1 { color : Grey;}
h2 {color : Blue;}</style>
</head>
<body>
<h1> Apps List: <xsl:value-of select="\#List_Type" /></h1>
<p>This is a list of all currently hot apps:</p>
<xsl:for-each select="\App">
<xsl:if test="\App\#installed == true">
<h2 style="color:Green;"><xsl:value-of select="\App\app_name" />(instaled)</h2>
</xsl:if>
<xsl:otherwise>
<h2><xsl:value-of select="\App\app_name" /></h2>
</xsl:otherwise>
<p style="font-style:bold;">App info:</p>
<table id="#gradient-style">
<tr><th>Category:</th><td><xsl:value-of select="\App\catogry" /></td></tr>
<tr><th>Verdion:</th><td><xsl:value-of select="\App\version" /></td></tr>
<tr><th>Description:</th><td><xsl:value-of select="\App\description" /></td></tr>
<tr><th>App Reviews:</th><td><xsl:for-each select="\App\reviews\review">
<span style="font-style:bold;"><xsl:value-of select="\App\reviews\review\reviewer_name" /></span>
| <xsl:value-of select="\App\reviews\review\review_date" />
| <xsl:value-of select="\App\reviews\review\review_Time" /><br/>
<span style="font-style:bold;">Rating:</span>
<xsl:value-of select="string(\App\reviews\review\rating" /> <br/>
<xsl:value-of select="\App\reviews\review\ontent" /><br/>
----------------------------------------------------------
</xsl:for-each>
</td></tr>
</table>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
this is the XML that tried with
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ShdenXSLT.xsl"?>
<Apps xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" List_Type="new releases" >
<App device_type="tablet" app_id="120">
<app_name>Meeting Manager</app_name>
<catogry>LifeStyle </catogry>
<catogry>Bussnisse </catogry>
<version>1.0</version>
<description>This app is about managing the bussnisse meeting</description>
<reviews>
<review>
<reviewer_name>Shaden</reviewer_name>
<review_date>2012-02-13</review_date>
<review_time>11:35:02</review_time>
<content>it was a useful app</content>
<rating>4.5</rating>
</review>
<review>
<reviewer_name>Mohamed</reviewer_name>
<review_date>2012-03-01</review_date>
<review_time>12:15:00</review_time>
<content>i really loved this app</content>
<rating>5.0</rating>
</review>
</reviews>
</App>
<App device_type="tablet" app_id="100">
<app_name>ToDoList</app_name>
<catogry>LifeStyle </catogry>
<version>3.4.2</version>
<description>a simple To Do List applecation</description>
<reviews>
<review>
<reviewer_name>Fahad</reviewer_name>
<review_date>2010-02-05</review_date>
<review_time>09:40:55</review_time>
<content>nice app</content>
<rating>4.0</rating>
</review>
</reviews>
</App>
</Apps>
You are using backslash (\) as your XPath separator (i.e. <xsl:value-of select="\#List_Type" />), which is incorrect. It should be a forward slash (/)

HTML entities do not render correctly in browser after XSLT transform

I have the following XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<example>
<contactInfo>
<id>12319221</id>
<name>Jerry P</name>
<market>
<name>Test</name>
<phone>800.555.1010</phone>
</market>
<agent>
<name>Test User</name>
<email>testuser#email.com</email>
</agent>
<summary>&#8220;Jerry just gets it!&#8221;</summary>
</contactInfo>
</example>
I am encoding special characters as html entities when I save this xml document, hence how the smart quotes are encoded as “ and &#8221.
And I use an XSL, via Java/Xalan, to transform the xml document to html:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="wsHost"></xsl:param>
<xsl:param name="serverId"></xsl:param>
<xsl:template match="/showcase">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Example</title>
</head>
<body>
<div id="profile">
<xsl:apply-templates/>
</div>
</body>
</html>
</xsl:template>
<!-- Contact Info section -->
<xsl:template match="/example/contactInfo">
<span class="sectionTitle">Contact Info:</span>
<div id="contactInfo">
<xsl:if test="name">
<strong>Candidate Name:</strong> <xsl:value-of disable-output-escaping="yes" select="name" /><br />
</xsl:if>
<xsl:if test="id">
<strong>Candidate ID:</strong> <xsl:value-of disable-output-escaping="yes" select="id" /><br />
</xsl:if>
<xsl:if test="market">
<xsl:if test="market/name">
<strong>Market Name:</strong> <xsl:value-of disable-output-escaping="yes" select="market/name" /><br />
</xsl:if>
<xsl:if test="market/phone">
<strong>Market Phone:</strong> <xsl:value-of disable-output-escaping="yes" select="market/phone" /><br />
</xsl:if>
</xsl:if>
<xsl:if test="agent">
<xsl:if test="agent/name">
<strong>Agent Name:</strong> <xsl:value-of disable-output-escaping="yes" select="agent/name" /><br />
</xsl:if>
<xsl:if test="agent/email">
<strong>Agent Email:</strong> <xsl:value-of disable-output-escaping="yes" select="agent/email" /><br />
</xsl:if>
</xsl:if>
<xsl:if test="summary">
<strong>Summary:</strong> <xsl:value-of disable-output-escaping="yes" select="summary" /><br />
</xsl:if>
</div>
<hr size="1" noshade="noshade" class="rule" />
</xsl:template>
</xsl:stylesheet>
The html that results from the transform is then written to the browser. Here is where I'm noticing a character encoding issue. The   (nbsp numeric value) show up as either black diamond question marks (firefox) or a box character (ie) and so do the entities that were previously encoded (“ / ”).
Also, maybe the biggest hint of all is that when transforming this xml file on a linux platform (then writing html to firefox) everything appears correctly. It's only when the transform is done from windows do the character encoding issues occur (in both firefox and ie).
Am I encoding the entities incorrectly or maybe not specify a character set somewhere?
You say you are using Java/Xalan. Are you prividing the output stream or stream writer? If so you need to explicitly set the encoding at that point:
... new OutputStreamWriter(stream,"UTF-8");
Just including the UTF8 headers does not actually cause the output file to be UTF8 encoded.
Well you havent set the encodeing in the HTML document for one. Dont know if thats the issue but that would be my first attempt to fix.
try adding:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
to your head.