I have a XHTML Template. I want to convert dynamically the xhtml file to xslt . Waht is the best way to do this?
Below written the XHTML content
<div>
{:header:}
<br />
{:date:}
<p>
{:mailingattn:} <br />
{:facilityname:} <br />
{:facilitystreet:} <br />
{:facilitystreet2:} <br />
{:facilitycity:}, {:facilitystate:} {:facilityzip:} <br />
{:facilitycountry:}
</p>
<p>
{:message:}
</p>
<p>
Sincerely,<br />
{:signature:}
</p>
{:footer:}
</div>
I don't know precisely the semantics of the macros used in your XHTML file, but the following transformation produces an XSLT stylesheet which is hopefully equivalent, and if not, should be easily tailored to your needs:
<?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">
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="#*"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:element name="xsl:stylesheet">
<xsl:attribute name="version" select="'2.0'"/>
<xsl:element name="xsl:template">
<xsl:attribute name="match" select="'/*'"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="regex">\{:([a-zA-Z0-9]*):\}</xsl:variable>
<xsl:analyze-string select="." regex="{$regex}">
<xsl:matching-substring>
<xsl:element name="xsl:value-of">
<xsl:attribute name="select" select="regex-group(1)"/>
</xsl:element>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="."/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>
Did you consider using XProc and <p:template> ?
http://www.w3.org/TR/xproc-template/#c.template
Related
I am using Umbraco v6.1.6 and what I want is simply display the images from the media directory I select using media picker.
The content of media directory is as below:
And I have created an XSLT file named ImageSlider.xslt and the content of that file are as below:
<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:umb="urn:umbraco.library"
exclude-result-prefixes="umb"
>
<xsl:output method="html" indent="yes" omit-xml-declaration="yes" />
<xsl:param name="currentPage" />
<xsl:template match="/">
<xsl:variable name="media" select="umb:GetMedia(1088, 0)" />
<xsl:if test="$media">
<img src="{$media/umbracoFile}" alt="{$media/altText}" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
here 1088 is the ID of the banner directory but it is not working at all. I am new to this.
Can anyone please help me ?
I'm assuming you want to select the folder and list all images underneath it. At the moment, your code is just trying to display the folder. You need something like this...
In my example, I'm using a multi-node tree picker and you can select images and folders, rendering out a csv. It will loop through it all and list out all the images
<xsl:for-each select="$source/value">
<xsl:variable name="imageId" select="number(current())" />
<xsl:if test="$imageId > 0">
<xsl:variable name="media" select="umbraco.library:GetMedia($imageId, 0)" />
<xsl:choose>
<xsl:when test="local-name($media) = 'Image'">
<xsl:call-template name="ImageBox">
<xsl:with-param name="imageId" select="$imageId"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="local-name($media) = 'Folder'">
<xsl:call-template name="LoopFolders">
<xsl:with-param name="folderId" select="$imageId"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template name="LoopFolders">
<xsl:param name="folderId"/>
<xsl:variable name="media" select="umbraco.library:GetMedia($folderId, 0)" />
<xsl:variable name="alt" select="$media/#nodeName" />
<div id="gallery">
<xsl:for-each select="umbraco.library:GetMedia($folderId, true())/Image">
<xsl:call-template name="ImageBox">
<xsl:with-param name="imageId" select="number(#id)"/>
</xsl:call-template>
</xsl:for-each>
</div>
</xsl:template>
<xsl:template name="ImageBox">
<xsl:param name="imageId"/>
<xsl:if test="$imageId > 0">
<xsl:variable name="media" select="umbraco.library:GetMedia($imageId, 0)" />
<xsl:if test="$media">
<xsl:variable name="url" select="$media/umbracoFile" />
<xsl:variable name="width" select="$media/umbracoWidth" />
<xsl:variable name="height" select="$media/umbracoHeight" />
<xsl:variable name="alt" select="$media/#nodeName" />
<img src="{$url}" alt="{$alt}" width="{$width}" height="{$height}" />
</xsl:if>
</xsl:if>
</xsl:template>
I'm working on a DDR Treeview menu for DotNetNuke to display only the selected Root items and its child node to be expanded. Here is what I'm trying to achieve.
(Left vertical menu)
Any advice please?
This is the xslt code and is currently displaying all root items.
<?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"/>
<xsl:param name="ControlID" />
<xsl:param name="Options" />
<xsl:template match="/*">
<xsl:apply-templates select="root" />
</xsl:template>
<xsl:template match="root">
<xsl:if test="node">
<ul class="treeview filetree" id="{$ControlID}">
<xsl:apply-templates select="node" />
</ul>
<script type="text/javascript">
jQuery(function($) {
$("#<xsl:value-of select="$ControlID" />").treeview(
<xsl:value-of select="$Options" disable-output-escaping="yes" />
);
});
</script>
</xsl:if>
</xsl:template>
<xsl:template match="node">
<li>
<xsl:if test="node and (#depth != 0 or #breadcrumb = 1)">
<xsl:attribute name="class">open</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="#enabled = 0">
<xsl:value-of select="#text" />
</xsl:when>
<xsl:otherwise>
<a href="{#url}">
<xsl:choose>
<xsl:when test="#selected=1">
<xsl:attribute name="class">selected breadcrumb</xsl:attribute>
</xsl:when>
<xsl:when test="#breadcrumb=1">
<xsl:attribute name="class">breadcrumb</xsl:attribute>
</xsl:when>
</xsl:choose>
<xsl:value-of select="#text" />
</a>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="node">
<ul style="list-item-style:none">
<xsl:apply-templates select="node" />
</ul>
</xsl:if>
</li>
</xsl:template>
</xsl:stylesheet>
It would help if you supplied an example of the input code you would like to transform.
I assume its basically something like this:
<root>
<node enabled="1" depth="1" text="Service" selected="true" breadcrumb="0"/>
<node>
<node>
<node/>
</node>
</node>
<node>
<node/>
</node>
<node/>
</root>
You can skip the first template-match and those first if-element and directly match only what you're interested in. Without testing, something like this should do the trick:
<!-- ... -->
<!-- process only "root" elements that have at least one "node" element -->
<xsl:template match="/root[node]">
<ul class="treeview filetree" id="{$ControlID}">
<xsl:apply-templates select="node" />
</ul>
<!-- ... -->
</xsl:template>
<xsl:template match="node">
<!-- ... -->
</xsl:template>
Without the source XML it's really hard to work out what you're trying to do here, but I'd say the main reason you're getting all nodes is the the template to match the node element is recursive and does not hide the descendants. If you add display:none to the style attribute on the ul element at the end of the node template (or change list-item-style to display), you may get what you want.
If you're only getting root items, you'll want to change the NodeSelector defined for the menu. I believe that the shorthand value RootChildren will give you what you want.
I've basically got an XML input structure like this:
...
<box type="rectangle" class="someOriginalClass">
<background bgtype="solid" />
<animation order="3" />
... children
</box>
and would like to transform it to
<div class="someOriginalClass rectangle solid animated order3">
...children
</div>
Note that neither background nor animation need to be there, and this is a reduced example, meaning that there could be more properties like these, with more attributes.
As well, animation and background are reused elsewhere.
My XSLT code so far is:
<xsl:template match="box">
<div class="{#someOldClass} {#type}">
<xsl:apply-templates select="./*" />
</div>
</xsl:template>
<xsl:template match="background">
<xsl:attribute name="class">
<xsl:value-of select="#bgtype"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="animation">
<xsl:attribute name="class">
animated order<xsl:value-of select="#order"/>
</xsl:attribute>
</xsl:template>
The problem with this code is that each template overrides the class attribute completely, dismissing already contained classes.
To solve this, I've tried:
a) rewriting old classes => value-of only gets input XML class (someOldClass)
<xsl:template match="animation">
<xsl:attribute name="class">
<xsl:value-of select="../#class"/>
animated order<xsl:value-of select="#order"/>
</xsl:attribute>
</xsl:template>
b) instead passing changes between templates with params => only one time, one way
<xsl:template match="box">
<div class="{#someOldClass} {#type}">
<xsl:apply-templates select="./*">
<xsl:with-param name="class" select="concat(#someOldClass,' ',#type)"/>
</xml:apply-templates>
</div>
</xsl:template>
<xsl:template match="animation">
<xsl:param name="class"/>
<xsl:attribute name="class">
<xsl:value-of select="$class"/>
animated order<xsl:value-of select="#order"/>
</xsl:attribute>
</xsl:template>
You see, I'm lacking a solution that will work with any number of class updates, with minimal redundancy.
BTW, I'm an XSLT beginner, so maybe there's some predestined feature that I've simply not yet come across.
Any ideas?
I've used this before. I'm not sure what your XML looks like but this may help get you on the right path.
<xsl:template match="box">
<xsl:param name="boxType" />
<li>
<xsl:variable name="boxClass">
<xsl:value-of select="$boxType"/>
<xsl:if test="#class1 = 1"> class1</xsl:if>
<xsl:if test="#class2 = 1"> class2</xsl:if>
<xsl:if test="#class3 = 1"> class3</xsl:if>
<xsl:if test="#class4 = 1"> class4</xsl:if>
<xsl:if test="#last = 1"> lnLast</xsl:if>
</xsl:variable>
<xsl:attribute name="class">
<xsl:value-of select="$boxClass"/>
</xsl:attribute>
</li>
</xsl:template>
I'm having trouble publishing an RSS feed from my Umbraco site. I found this Umbraco.TV video and tried to follow the instructions there using an XSLT selector to select all nodes of a give type, like so:
umbraco.library.GetXmlAll()/node [#nodeTypeAlias='Alias]/node
As sugested here but that didn't work. Apparently the schema has changed or something. When this didn't work I looked for a plugin to do this kind of stuff and was amazed to find just 2 plugins, both of them with little-to-no documentation and neither seemed to work (first plugin, second plugin).
So once and for all, I'd like to have a definite answer - how does one publish an RSS feed in Umbraco?
Here's an XSLT that we use for News Items RSS (News Items are under a News Page). Let me know if that helps. I also have versions for Blogs.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:rssdatehelper="urn:rssdatehelper"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets"
exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:param name="currentPage"/>
<!-- Update these variables to modify the feed -->
<xsl:variable name="RSSNoItems" select="/macro/RSSNoItems"/>
<xsl:variable name="RSSTitle" select="/macro/RSSTitle"/>
<xsl:variable name="SiteURL" select="concat('http://',umbraco.library:RequestServerVariables('HTTP_HOST'))"/>
<xsl:variable name="RSSDescription" select="/macro/RSSDescription"/>
<xsl:variable name="source" select="/macro/source"/>
<!-- This gets all news and events and orders by updateDate to use for the pubDate in RSS feed -->
<xsl:variable name="pubDate">
<xsl:for-each select="umbraco.library:GetXmlNodeById($source)/* [#isDoc and string(umbracoNaviHide) != '1']">
<xsl:sort select="./newsDate" order="descending" />
<xsl:if test="position() = 1">
<xsl:value-of select="./newsDate" />
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:template match="/">
<!-- change the mimetype for the current page to xml -->
<xsl:value-of select="umbraco.library:ChangeContentType('text/xml')"/>
<xsl:text disable-output-escaping="yes"><?xml version="1.0" encoding="UTF-8"?></xsl:text>
<rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
>
<channel>
<title>
<xsl:value-of select="$RSSTitle"/>
</title>
<link>
<xsl:value-of select="$SiteURL"/>
</link>
<pubDate>
<xsl:value-of select="$pubDate"/>
</pubDate>
<generator>umbraco v4</generator>
<description>
<xsl:value-of select="$RSSDescription"/>
</description>
<language>en</language>
<xsl:for-each select="umbraco.library:GetXmlNodeById($source)/* [#isDoc and string(umbracoNaviHide) != '1']">
<xsl:sort select="./newsDate" order="descending" />
<xsl:if test="position() <= $RSSNoItems">
<xsl:call-template name="RSSitem">
<xsl:with-param name="node" select="current()"/>
</xsl:call-template>
</xsl:if>
</xsl:for-each>
</channel>
</rss>
</xsl:template>
<xsl:template match="node">
<xsl:if test="position() <= $RSSNoItems">
<item>
<title>
<xsl:value-of select="#nodeName"/>
</title>
<link>
<xsl:value-of select="$SiteURL"/>
<xsl:value-of select="umbraco.library:NiceUrl(#id)"/>
</link>
<pubDate>
<xsl:value-of select="umbraco.library:FormatDateTime(./newsDate,'r')" />
</pubDate>
<guid>
<xsl:value-of select="$SiteURL"/>
<xsl:value-of select="umbraco.library:NiceUrl(#id)"/>
</guid>
<content:encoded>
<xsl:value-of select="concat('<![CDATA[ ', ./bodyText,']]>')" disable-output-escaping="yes"/>
</content:encoded>
</item>
</xsl:if>
</xsl:template>
<xsl:template name="RSSitem">
<xsl:param name="node"/>
<item>
<title>
<xsl:value-of select="$node/#nodeName"/>
</title>
<link>
<xsl:value-of select="$SiteURL"/><xsl:value-of select="umbraco.library:NiceUrl($node/#id)"/>
</link>
<pubDate>
<xsl:value-of select="umbraco.library:FormatDateTime(./newsDate,'r')"/>
</pubDate>
<dc:creator><xsl:value-of select="#writerName"/></dc:creator>
<xsl:for-each select="umbraco.library:Split($node/categories, ',')/value">
<xsl:sort data-type="text" order="ascending"/>
<category>
<xsl:value-of select="current()"/>
</category>
</xsl:for-each>
<guid>
<xsl:value-of select="$SiteURL"/><xsl:value-of select="umbraco.library:NiceUrl($node/#id)"/>
</guid>
<description>
<xsl:value-of select="concat('<![CDATA[ ', $node/summary,']]>')" disable-output-escaping="yes"/>
</description>
<content:encoded>
<xsl:value-of select="concat('<![CDATA[ ', $node/bodyText,']]>')" disable-output-escaping="yes"/>
</content:encoded>
</item>
</xsl:template>
</xsl:stylesheet>
I'm trying to write some xsl to style an RSS feed. I need to trim the first 10 characters off the title of each item.
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/rss">
<ul>
<xsl:for-each select="channel/item">
<li><strong><xsl:value-of select="title"/>
</strong>
More</li>
</xsl:for-each>
</ul>
</xsl:template>
<xsl:template name="trimtitle">
<xsl:param name="string" select="." />
<xsl:if test="$string">
<xsl:text>Foo</xsl:text>
<xsl:call-template name="trimtitle">
<xsl:with-param name="string" select="substring($string, 10)" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="title">
<xsl:call-template name="title" />
<xsl:value-of select="." />
</xsl:template>
</xsl:stylesheet>
I think you should write your substring function as this:
substring($string,1, 10)
Look at here
http://www.zvon.org/xxl/XSLTreference/Output/function_substring.html
What are you doing in your trimtitle template?
Why are you calling trimtitle recursive..?
The easiest way to show a trimmed string is with:
<xsl:value-of select="substring(title,0,10)"/>