Archive for XSLT 2.0

Tokenize Me

While working with a customer recently we wanted to pull items from multiple libraries that were similar in structure to show the current status of documents in an advanced chart.  The results of the data were to be shown in columns stacked by status by library.

How to dynamically retrieve the friendly name of the library from each item being returned in the CAPS response? An easy, yet inelegant, method is to add a text column to the libraries that simply defaults to a hard-coded value with the library’s name when a document is added.  But, why add something if it is not really needed, and what if you are dealing with more than just a few libraries?

XSLT 2.0 to the rescue.  One of the great functions of XSLT 2.0 is the tokenize function.  It is pretty easy to use, yet very powerful for a variety of tasks.  In this scenario I wanted to grab the name of the library from an item using the “FileDirRef” column and I didn’t want to apply a recursive template or such to get to it.  I wanted to keeps things as simple and lightweight as possible.  So here it is:


Just tokenize the “@ows_FileDirRef” value from the CAPS response using the “/” as the delimiter and then tell it you want the last value using the predicate filter [last()] on the result.

Happy building!

Quick Tip – Attribute Value Templates in XSLT

Previously, I blogged about a quick & easy shorthand method for referencing an XSL variable within an attribute value – this capability is really a subset of a capability called “Attribute Value Templates” in XSL (reference).

What’s great about what I’ll call AVTs for short is that you’re not limited to just referencing existing XSL variables; once an AVT is instantiated – by use of the wrapping {} curly brackets – that attribute can then be any valid XSL expression.

Take for example a common use case of dynamically generating some HTML using XSL and, in doing so, wanting to create HTML attributes using data points from your source XML. In the past, you may have done something like this:

   <xsl:attribute name="id">
      <xsl:value-of select="concat('Task',TaskID)"/>
   <xsl:value-of select="Title"/>

But using an AVT, this same line could be re-written as:

<div id="{concat('Task',TaskID)}">
   <xsl:value-of select="Title"/>

This is just a simple example but, in general, if you can create an expression as part of a “value-of select”, you can do it within an AVT. Support for full expressions within an AVT thus helps ensure you can write stylesheets that are now both smaller and easier to read.

Quick Tip – Shorthand Variable References in XSLT

Here’s a quick tip – next time you’re writing some XSL and want to include a variable within the attribute value of a node, don’t waste time & code doing something like this:

<xsl:variable name="VarName" select="SomeData"/>
  <xsl:attribute name="AttrName">
    <xsl:value-of select="$VarName"/>

Instead, you can use this shorthand notation for referencing a variable directly within an element attribute:

<xsl:variable name="VarName" select="SomeData"/>
<MyElement AttrName="{$VarName}"/>


XSLT 2.0 – Even More on Dates

Recently, I needed to get the minimum and maximum dates from a SharePoint Task list. With XSLT 1.0, you typically accomplish this by iterating over your rows and sorting them in the order you want, then grabbing the first or last value to get the min or max date you want.  This can get cumbersome when you need to do this on more than a couple of fields.

So I took advantage of the opportunity to see what XSLT 2.0 had to offer.  Sure enough there is a min() and max() function and they work just like you would expect them to.

Using a Task list as an example, we can quickly find minimum start and maximum due dates for the entire set of tasks with two lines of XSL applied to our raw CAPS output.


<xsl:value-of select=” min(NewDataSet/Tasks/cw:listitems/rs:data/z:row/@ows_StartDate/xs:dateTime(.))”/>



<xsl:value-of select=” max(NewDataSet/Tasks/cw:listitems/rs:data/z:row/@ows_DueDate/xs:dateTime(.))”/>


We have to append our selected node with “/xs:dateTime(.)” so that the XSLT 2.0 engine will compare values as dates and not strings.

You will also want to make sure that you are including “<DateInUtc>TRUE</DateInUtc>” in the CAML of your CAPS call as well.

If you need to refresh your memory about working with dates in xslt 2.0 and CAPS here are our two prior blogs covering formatting and doing calculations.

XSLT 2.0 – More on Dates

Dates.  The “when” of it all.  Working with dates can be frustrating when building client side applications for SharePoint due to the limitations of XSLT 1.0.   Our resident CAPS and XSLT 2.0 expert, Steve Evangelista, blogged a while back about how much easier it is to format dates with our new CAPS service because you can leverage XSLT and XPath 2.0 functions. Having recently helped Steve with a project to create a complicated Gantt chart for resource management, I wanted to take a moment to repeat Steve’s message and also let all of you know how powerful and easy it is to perform date calculations with XSLT 2.0.

One of the first things we need to do is make sure we properly reference the XML namespaces we’ll need to make use of in our xsl:stylesheet node; namely:

The first thing you have to do when with working with dates in XSLT 2.0 is to make sure you recast your date values from your underlying XML, which are all strings, to “date”, “time” and/or “dateTime” types depending on your needs.

You are now ready to do some calculations.  Lets start with a common scenario — finding the difference between two dates:

<xsl:value-of “select=”xs:dateTime(DateTime1)-xs:dateTime(DateTime2)” />

DateTime1 and DateTime2 are two date values from your data in the format of  “yyyy-MM-ddThh:mm:ss” for the dateTime type.  If you’re only interested in dates then use xs:date and if you are only interested in time, use xs:time instead of xs:dateTime.

This gets you a raw value, but we can get what we’re really after by wrapping that calculation in another XPath function.

<xsl:value-of select=”days-from-duration(xs:dateTime(DateTime1)-xs:dateTime(DateTime2))” />

The XPath function “days-from-duration” converts the raw results of our date calculation into something meaningful for your grid display or chart.

If we were only interested in the number of hours, we could have used the XPath function “hours-from-duration”.

It’s that easy.  No need to use any complicated XSLT 1.0 templates, depend on EXSLT libraries or write javascript.   All you need to do is include these XSLT 2.0 functions in XSL  stylesheets that you can apply to your CAPS requests’ XML output.

The website is a great place to learn more about XML, XSLT & XPath. For a listing of XPath 2.0 date/time/duration functions you can go directly to this page:

Have fun and keep building.

Adding XSLT 2.0 IntelliSense to Visual Studio

With the release of the CorasWorks Application Service (CAPS), the ability to leverage XSLT 2.0 within our SharePoint applications has been a major boost to our capability set. And for anyone that’s written XSLT, you know using an IDE that is schema-aware, and thus able to provide element, attribute and value completion options can make it all the easier.

As someone that works predominantly in Visual Studio, I knew there must be an option to switch the default XSLT schema from 1.0 (which is the default because that’s all native .Net supports) to 2.0. And sure enough, there is!

  1. Browse to the install directory for Visual Studio on your machine. By default this is typically “C:\Program Files\Microsoft Visual Studio XX.x” where “XX.x” is your version of Visual Studio. If you’re using a 64-bit machine, it will be the x86 version of the “Program Files” directory.
  2. Within the install directory, open the “Xml” folder, then the “Schemas” folder
  3. Make a copy of the existing “xslt.xsd” file therein; I renamed mine to “schema-for-xslt1.0.xsd”
  4. Download the official XSLT 2.0 XSD from W3C here and save it as “xslt.xsd” to the same Schemas directory above.
  5. If you have Visual Studio currently open, restart it.
  6. Once you open an XML, XSL or XSLT file, the XML menu will appear in the Toolbar:
  7. Click the “Schemas…” option, which will open the XML Schemas dialog. Locate the XSD file copied in Step 3 and toggle “Use” option to Disabled:
  8. The newly downloaded XSD for XSLT 2.0 should already be enabled by default but, if not, be sure to do so.
  9. Enjoy XSLT 2.0 IntelliSense within Visual Studio :)

Split, Join & Distinct – Working with Strings in XSLT 2.0

Here at CorasWorks, the ability to leverage XSLT 2.0 within our SharePoint-based applications – thanks to the CorasWorks Application Service – has added a lot in the way of efficiency. We’ve previously blogged about the myriad of Date Formatting options (here), and using RegEx to parse content from the ugly HTML markup SharePoint creates for multi-line text fields (here). Another area though that has improved vastly with XSLT 2.0 is string functions; specifically, let’s look at the tokenize(), string-join() and distinct-values() functions.

As is often the case, it’s not that these sort of routines weren’t possible in XSLT 1.0; they were just inefficient, took more lines of script to write and were possibly even prohibitively complex to come up with on your own. The new functions in XSLT 2.0, by contrast, are optimized, compact and intuitive to write.

Take splitting a string based on some delimiter, a fairly common use case; using the tokenize() function within a for-each statement makes this trivial. For example, SharePoint frequently stores certain data as a string delimited by the characters “;#” – item attachments and multi-select Choice, Person & Lookup values are just some of the data points SharePoint stores in this format. With XSLT 2.0, these values could be parsed out simply as such:

<xsl:for-each select=“tokenize(MyColumn,’;#’)”>

<Item><xsl:value-of select=“.”/></Item>


The inverse is also equally straightforward; assume you have an XML node set you’d like to concatenate the values for using some delimiter of your choosing. This example would take the Assigned To values for all Tasks and join them into a single element called “StringJoin” with each value separated by a semicolon and a space using the string-join() function:


<xsl:value-of select=”string-join(Tasks/AssignedTo/text(),’; ‘)”/>


Following that example though, if more than one Task is assigned to the same person, you’d get duplicate names in the “StringJoin” value; so let’s see how a node set could be created with just the distinct names via the distinct-values() function:

<xsl:for-each select=“distinct-values(Tasks/AssignedTo)”>

<DistinctName><xsl:value-of select=“.”/></DistinctName>


These three functions go a long way to optimizing and simplifying the XSLT you may write, and we’re lucky to be the only application platform on SharePoint that supports them and all the other advantages XSLT 2.0 affords!

Formatting Dates & Times in XSLT 2.0

The CorasWorks Application Service brings the power of XSLT 2.0 to SharePoint 2010 & 2013 – and with it, the myriad of new functions and capabilities the 2.0 spec includes. A common need, especially when working with SharePoint data, is to reformat Date and Time values as SharePoint returns them in the format yyyy-MM-dd hh:mm:ss (or sometimes even yyyy-MM-ddThh:mm:ssZ). Let’s deconstruct this real quick, since knowing your input will ensure you apply the right options to get the desired output.

Let’s reference the date CAPS was released – July 15, 2013 at midnight – for all the below:

Format String Description Result
yyyy 4-digit year 2013
MM 2-digit month 07
dd 2-digit day 15
hh 2-digit hour (12-hour format) 12
mm 2-digit minute 00
ss 2-digit second 00

With XSLT 2.0, not only is Date & Time formatting now supported natively, but the options you can specify are extremely flexible, including multilingual support (dependent on support being enabled in your XSL processor).

Here are some of the most common use-cases and how to implement them:

Format String Description Result
Default US format 7/15/2013
2-digit month, slash,
2-digit day, slash,
2-digit year
‘[D1o] [MNn], [YWw]‘)
Ordinal day month name,
year as words
15th July,
Two Thousand and Thirteen
‘The [Dwo] day of [MNn], [Y]‘)
Date as a word, name of month, year The fifteenth day of July, 2013
‘[FNn], [MNn] [D1o], [Y]‘)
Day of week, month name, year Monday, July 15th, 2013
‘[MNn] [D1o] is the [dwo] day of [Y]‘)
Day of year July 15th is the
one hundred and ninety-sixth day of 2013
‘[FNn,3-3]., [MNn] [D1o], [Y]‘)
Day of week abbrev., month, day ordinal,
Mon., July 15th, 2013
‘[MNn,3-3]. [D1o], [Y]‘)
Abbreviated month, day ordinal, year Jul. 15th, 2013
‘[H]:[m] is the [m1o] minute of the [Hwo] hour’)
Minute ordinal and
hour ordinal
8:30 is the 30th minute of the eighth hour
‘[h02]:[m] – or [h02][m] in military format’)
Time in 24hr clock, or in military format 08:30 – or 0830 in military format
‘[H]:[m] can be clarified as [H]:[m] [P]‘)
Time with AM/PM lowercase 8:30 can be clarified as 8:30 a.m.
‘[H]:[m] can be clarified as [H]:[m] [PN]‘)
Time with AM/PM uppercase 8:30 can be clarified as 8:30 A.M.
‘[H]:[m] can be clarified as [H]:[m][PN,2-2]‘)
Time with AM/PM uppercase and no periods 8:30 can be clarified as 8:30AM

Hopefully these cover all the common usage scenarios and you can take advantage of the greatly improved Date & Time formatting in XSLT 2.0. For more info, check out the detailed spec on the W3 site here.

Grouping in XSLT 2.0

I have been helping one of my colleagues on an engagement that has a complex project Gantt chart as part of a custom Project Lifecycle Management application.  The chart involves multi-level grouping of the data from a number of SharePoint Lists so it was an excellent opportunity to take advantage of the ability to utilize XSLT 2.0 as supported by the CorasWorks Application Service (available for both SharePoint 2010 & 2013).

XSLT 2.0 has some significant advantages over XSLT 1.0, including improved support for data types, custom functions and data parsing.  One of the other major improvements – and the reason I was excited about working on the Gantt chart solution – is the ease with which data can be grouped.  Grouping and especially multi-level grouping with XSLT 1.0 can be quite laborious and prone to errors.  A popular and efficient method of grouping in XSLT 1.0 is Meunchian grouping, wherein keys are defined that will be used in the select attribute of the <xsl:for-each> instruction so the processor knows which data values to group on.  Each additional level requires that a new key be defined and that the grouping value used be a concatenation of the preceding key’s value with the current grouping value.

Various examples of grouping with XSLT 1.0 are located at Jeni Tennison’s site, and here’s the basic form for multi-level grouping:

<xsl:key name="service_row" match="SetDailySetRpt:SettleItem" use="SetDailySetRpt:ServiceCode" />

<xsl:key name="exchange" match="SetDailySetRpt:SettleItem" use="concat(SetDailySetRpt:ServiceCode, ' ', SetDailySetRpt:ExchangeName, ' ', SetDailySetRpt:ExchangeCode)" />

<xsl:variable name="service_items" select="key('service_rows', SetDailySetRpt:ServiceCode)" />

<xsl:for-each select="$service_items[generate-id() = generate-id( key('exchange', concat(SetDailySetRpt:ServiceCode, ' ', SetDailySetRpt:ExchangeName, ' ', SetDailySetRpt:ExchangeCode))[1])]">
  <xsl:value-of select="SetDailySetRpt:ExchangeName" />
  <xsl:text> - </xsl:text>
  <xsl:value-of select="SetDailySetRpt:ExchangeCode" />

I have used this grouping method with great success on a variety of reports and displays, but it can be frustrating to make sure you have all the keys, variables and select attributes within the <xsl:for-each> instruction properly written.

With XSLT 2.0, life is much simpler when it comes to grouping.  No longer do you need to define keys and declare variables.  Here’s an example of multi-level grouping with XSLT 2.0:

<xsl:for-each-group select="NewDataSet/Data" group-by="LEVEL_1_DATA">
  <xsl:value-of select="current-grouping-key()"/>
  <xsl:for-each-group select="current-group()" group-by=" LEVEL_2_DATA ">
    <xsl:value-of select="current-grouping-key()"/>
    <xsl:for-each-group select="current-group()" group-by="LEVEL_2_DATA ">
      <xsl:value-of select="current-grouping-key()"/>
      <xsl:for-each select="current-group()">
        <xsl:value-of select="ITEMS"/>

The first thing you’ll notice is that we are using XSLT 2.0’s <xsl:for-each-group> instruction at each grouping level and that there is a group-by attribute that lets us quickly define what we want to group the populate of data on at that level.  As we traverse down the hierarchy, we can simply reference the current group we are in by setting the select attribute to use the current-group() XPATH expression. For more information, check out this great discussion about XSLT 2.0’s <xsl:for-each-group> instruction and its various attributes can be found here.

Using XSLT 2.0 to remove HTML Tags from a Value

htmlBuilding applications in SharePoint, as we do here at CorasWorks, often requires dealing with the output of what SharePoint calls “Rich Text” and “Enhanced Rich Text” fields. At the end of the day, if you’re attempting to do any XSL transformation on XML data that includes HTML content, you run the risk of the HTML causing errors when parser attempts to process it. One old trick is to use the “disable-output-escaping” attribute but this itself can be limiting.

Enter XSLT 2.0, which is supported within the CorasWorks Application Service (CAPS), and a simple yet elegant solution is only 6-lines of XSL away!

Take an example column value you get from SharePoint for one of these rich text fields:

<div   clas=”FDRDS43543fSDF”><font size=”3″>This is what I <em>really </em>need to test –   does it <font color=”#ff0000″>strip</font>   out   the <strong>HTML </strong>in here…?</font></div>


For the purposes of your transformed output though, you really just need the raw text, stripped of all HTML tags; more like this:

This   is what I really need to test – does it strip out the HTML in here…?


The way to achieve this result with XSLT 2.0 is:

<xsl:variable name=”StripHTML”><![CDATA[<\s*\w.*?>|<\s*/\s*\w\s*.*?>]]></xsl:variable><xsl:analyze-string select=”@ows_Body” regex=”{$StripHTML}”><xsl:non-matching-substring><xsl:value-of select=”.”/>




Leveraging the analyze-string element, a Regular Expression statement (set via the “regex” attribute) is used to parse an input (set via the “select” attribute); then, every substring within the source input is bucketed between two sets – those that matched the Regular Expression (xsl:matching-substring) and those that do not (xsl:non-matching-substring).

In this use, the Regular Expression catches any opening or closing HTML tag, regardless of name, attributes, etc. By then discarding, or not defining, any instruction for those matching substrings, they’re effectively dropped. The non-matching substrings are looped through and outputted as-is, leaving a nicely scrubbed value, devoid of any HTML tags.

The new analyze-string element in XSLT 2.0 is a useful and powerful upgrade over XSLT 1.0, and one we’re pleased to have access to within SharePoint thanks to CAPS!