I need to parse Visual Studio automatically generated XML documentation to create a report. I decided to use XSLT but I'm very new to it and need help. Common template is:
<doc>
<members>
<member name="F:MyNamespace">
<summary>Some text</summary>
</member>
</members>
</doc>
I want to isolate members with name which begins on some word, for example, P:Interfaces.Core. I decided to use RegExp in select statement.
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/TR/xpath-functions/">
<xsl:template match="/" >
<html xmlns="http://www.w3.org/1999/xhtml">
<body style="font-family:Tahoma">
<p>Interfaces list:</p>
<table>
<xsl:for-each select="doc/members/member">
<xsl:sort order="ascending" />
<xsl:value-of select="fn:matches(., 'P\..+')" />
<br />
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Why does I'm getting error:
Namespace http://www.w3.org/TR/xpath-functions does not contain any functions >
Where am I wrong? I found such code in examples, including w3c.org!
There is however an outofjail.get() with .net: there's always the possibility of passing a task to an Extension Object.
Not good practice since it's an extension to XSLT, but sometimes you have to go with what works.
These functions are from XPath 2.0 in XSLT 2.0. .NET XSLT is at 1.0 and your xsl namespace reflects that.
If you are working exclusively in MS XML you can add custom functions written in a .net language of your choice. See the example on MSDN (they use JScript). Then you could use regexes.
However, you should be able to use the starts-with xslt function to do what you need.
In case you're performing the transformation with Visual Studio X, where X is not greater than 2008, this would be processed by an XSLT 1.0 processor (.NET's
XslCompiledTransform
orXslTransform
). XSLT 1.0 uses XPath 1.0, not XPath 2.0 and its F & O (Functions and Operations), which only became a W3 Recommendation last year.You have two options:
Use a compliant XSLT 2.0 processor. If you prefer to stay within the .NET platform, then a suitable choice is Saxon.NET
Just use the XPath 1.0 function
starts-with()
, which is sufficient to solve the current problem.The expression:
starts-with(., 'P:Interfaces')
is evaluated totrue()
if the string value of the context node starts with the string 'P:Interfaces' and tofalse()
otherwise.Another Xpath 1.0 function that may come handy for such type of processing is the function
contains()
.Xpath's 2.0 function
ends-with()
can be emulated in XPath 1.0 in the following way:ends-with(s1, s2)
====substring
(s1,string-length
(s1)-string-length
(s2)+1)=s2where "
===
" means is "equivalent to".Here we also used the XPath 1.0 functions
substring()
andstring-length()
.