tags:

views:

1041

answers:

4
+2  Q: 

RegExp in XSLT

Hi all! 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"&gt;
      <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 [ttp://www.w3.org/TR/xpath-functions does not contain any functions > Where am I wrong? I found such code in examples, including w3c.org!

A: 

These functions are from XPath 2.0 in XSLT 2.0. .NET XSLT is at 1.0 and your xsl namespace reflects that.

AnthonyWJones
+2  A: 

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.

Jennifer
MS' implementation of XSLT doesn't support 2.0 functions. You have to use an external XSLT library like Saxon. More info here: http://stackoverflow.com/questions/94047/are-net-35-xpath-classes-and-methods-xslt-20-compatible
Will
A: 

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.

annakata
+3  A: 

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 or XslTransform). 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:

  1. Use a compliant XSLT 2.0 processor. If you prefer to stay within the .NET platform, then a suitable choice is Saxon.NET

  2. 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 to true() if the string value of the context node starts with the string 'P:Interfaces' and to false() 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)=s2

where "===" means is "equivalent to".

Here we also used the XPath 1.0 functions substring() and string-length().

Dimitre Novatchev
Hi! Thanks a lot for your answer!I already done something like you're talking about - I mean XPath 1.0, I use exactly what you said - starts-with(@name, 'T:MyNamespaces.Interfaces') and contains().
abatishchev