Extending XSLT with saxon C#
Added by Anonymous almost 16 years ago
Legacy ID: #5809206 Legacy Poster: pvallone (pvallone)
Hi, Using the examples (C#), I am trying to write an extension in C# and call it from with in the application. I am trying to pass a parameter to the stylesheet as an "external object". I am confused on how to create the namespace in my xslt. I get the following error: At line 12: XPath syntax error at char 14 on line 12 in {ext:getFile(.)}: Cannot find a matching 1-argument function named {clitype:SaxonExtensionCS.FileExist}getFile() Thanks for the help. Here is my C# class: namespace SaxonExtensionCS{ public partial class Form1 : Form{ public Form1(){ InitializeComponent(); } private void button1_Click(object sender, EventArgs e){ XmlDocument doc = new XmlDocument(); Processor processor = new Processor(); XmlTextReader xslt = new XmlTextReader(Application.StartupPath + "\test.xsl"); XmlTextReader xmlTextReader = new XmlTextReader(Application.StartupPath + "\data.xml"); Serializer serializer = new Serializer(); XsltCompiler compiler = processor.NewXsltCompiler(); try{ compiler.ErrorList = new ArrayList(); XsltTransformer transformer = compiler.Compile(xslt).Load(); doc.Load(xmlTextReader); XdmNode input = processor.NewDocumentBuilder().Wrap(doc); transformer.InitialContextNode = input; // Call my method/function FileExist fs = new FileExist(); transformer.SetParameter(new QName("", "timezone"), XdmAtomicValue.wrapExternalObject(TimeZone.CurrentTimeZone)); transformer.SetParameter(new QName("", "fileUtil"), XdmAtomicValue.wrapExternalObject(fs)); serializer.SetOutputProperty(Serializer.INDENT, "yes"); serializer.SetOutputStream(new FileStream(Application.StartupPath + "\ExampleSimple2.html", FileMode.Create, FileAccess.Write)); transformer.Run(serializer); }catch (Exception ex){ MessageBox.Show(ex.Message, "Error"); foreach (StaticError error in compiler.ErrorList) { textBox1.Text = "At line " + error.LineNumber + ": " + error.Message; } }finally{ serializer.Close(); xslt.Close(); xmlTextReader.Close(); } } } public class FileExist { Boolean exist = false; public Boolean getFile(String myFile) { exist = File.Exists(myFile); return exist; } } } My XSLT: <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tz="clitype:System.TimeZone" exclude-result-prefixes="tz" xmlns:ext="clitype:SaxonExtensionCS.FileExist"> <xsl:param name="timezone" required="yes"/> <xsl:param name="fileUtil" required="yes"/> <xsl:template match="/"> <out timezone="{tz:StandardName($timezone)}"> <xsl:text>test</xsl:text> <xsl:for-each select="//file"> <xsl:text>File </xsl:text> <xsl:value-of select="."/> <xsl:text> is </xsl:text> <xsl:value-of select="ext:getFile(.)"/> </xsl:for-each> </out> </xsl:template> </xsl:stylesheet>
Replies (7)
Please register to reply
RE: Extending XSLT with saxon C# - Added by Anonymous almost 16 years ago
Legacy ID: #5809321 Legacy Poster: Michael Kay (mhkay)
Try changing the call <xsl:value-of select="ext:getFile(.)"/> to <xsl:value-of select="ext:getFile($fileUtil, .)"/> For non-static methods there is an extra first argument, which is the object that acts as the target of the method being called. If this doesn't work it may be a dynamic loading problem: try using the -TJ argument for better diagnostics.
RE: Extending XSLT with saxon C# - Added by Anonymous almost 16 years ago
Legacy ID: #5809379 Legacy Poster: pvallone (pvallone)
Hi Michael, I get the same error. At line 12: XPath syntax error at char 25 on line 12 in {ext:getFile($fileUtil, .)}: Cannot find a matching 2-argument function named {clitype:SaxonExtensionCS.FileExist}getFile() I also tried making the getFile function static, but still get a compile error. As for using -TJ, I am not running from the command line, but rather calling it from my application. Thanks for the help. Phil
RE: Extending XSLT with saxon C# - Added by Anonymous almost 16 years ago
Legacy ID: #5809426 Legacy Poster: Michael Kay (mhkay)
When running from an application the equivalent of the -TJ option is processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true")
RE: Extending XSLT with saxon C# - Added by Anonymous almost 16 years ago
Legacy ID: #5809767 Legacy Poster: pvallone (pvallone)
Hi Michael, I get the same error. At line 12: XPath syntax error at char 25 on line 12 in {ext:getFile($fileUtil, .)}: Cannot find a matching 2-argument function named {clitype:SaxonExtensionCS.FileExist}getFile() I also tried making the getFile function static, but still get a compile error. As for using -TJ, I am not running from the command line, but rather calling it from my application. Thanks for the help. Phil
RE: Extending XSLT with saxon C# - Added by Anonymous almost 16 years ago
Legacy ID: #5810107 Legacy Poster: pvallone (pvallone)
Hi Michael, Adding processor.SetProperty("http://saxon.sf.net/feature/trace-external-functions", "true") does not return anything extra, however I got it working (from command line and from the application). First I had to change the getFile method to static, 2nd the function needs to be its own assembly (*.dll). Originally, I had the main application and the FileExist in the same namespace. I updated the wiki, however the code blocks on the wiki do not seem to be working: http://saxon.wiki.sourceforge.net/CallingDotNet Thanks for the help!
RE: Extending XSLT with saxon C# - Added by Anonymous almost 16 years ago
Legacy ID: #5810323 Legacy Poster: Michael Kay (mhkay)
Thanks for adding your experiences to the Wiki. Getting this working still seems to be something of a black art, I'm afraid: I've found things that work and things that don't work, and I'm never all that sure why.
RE: Extending XSLT with saxon C# - Added by Anonymous almost 16 years ago
Legacy ID: #5810488 Legacy Poster: pvallone (pvallone)
My pleasure Michael, Its the least I can do as you are always helpful. Best Regards, Phil V
Please register to reply