Run XQuery with vb .net
Added by Anonymous almost 16 years ago
Legacy ID: #6835736 Legacy Poster: NickDiamond (nickdiamond_80)
Hi, I am trying to start a XQuery-file from visual basic dotnet (using visual studio 2008). I have found the saxon api for vb, but there are not the needed elements I know from java. Also I found the dll from "Microsoft.Xml.XQuery". But this one is old, and seems not to provide complex xquery-files. Can someone explain which dll(s) from saxon I need, and how should the code look like !??! This is what I use in java ( maybe there is the same way in vb) : ByteArrayOutputStream result = new ByteArrayOutputStream(); Configuration config = new Configuration(); config.setHostLanguage(Configuration.XQUERY); StaticQueryContext sqc = new StaticQueryContext(config); String query ="<result>{for $r in doc('c:/bla.xml')// ....bla... return $r}</result>"; XQueryExpression exp = sqc.compileQuery(query); Result r = new StreamResult(result); DynamicQueryContext dynamicContext = new DynamicQueryContext(config); exp.run(dynamicContext, r, props); byte[] baos = result.toByteArray(); Greets, ND
Replies (13)
Please register to reply
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6836171 Legacy Poster: Michael Kay (mhkay)
The Saxon API on .NET is very similar in design to the s9api interface on Java (in fact, it was the model for the design of s9api). It's documented at http://www.saxonica.com/documentation/dotnetdoc/index.html and there are sample applications included in the saxon-resources distribution at http://downloads.sourceforge.net/saxon/saxon-resources9-1-0-1.zip (see file samples/cs/Examples.cs) The APIs are in namespace Saxon.Api, which is in the DLL saxon9api.dll Here is one of the examples: public override void run(Uri samplesDir) { Processor processor = new Processor(); XQueryCompiler compiler = processor.NewXQueryCompiler(); compiler.BaseUri = samplesDir.ToString(); compiler.DeclareNamespace("saxon", "http://saxon.sf.net/"); XQueryExecutable exp = compiler.Compile("<saxon:example>{static-base-uri()}</saxon:example>"); XQueryEvaluator eval = exp.Load(); Serializer qout = new Serializer(); qout.SetOutputProperty(Serializer.METHOD, "xml"); qout.SetOutputProperty(Serializer.INDENT, "yes"); qout.SetOutputProperty(Serializer.SAXON_INDENT_SPACES, "1"); qout.SetOutputStream(new FileStream("testoutput.xml", FileMode.Create, FileAccess.Write)); Console.WriteLine("Output written to testoutput.xml"); eval.Run(qout); } Actually, the way that IKVM works, you could probably write your C# application to use the underlying Java classes such as net.sf.saxon.Configuration directly (most of them are exposed in saxon9.dll), but it's not the way I would recommend. Michael Kay http://www.saxonica.com/
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6837034 Legacy Poster: NickDiamond (nickdiamond_80)
Hey Michael, Thank you very much !!!!! The "Serializer" is the right way (see code at the end) ;) There is one problem left : I want to fill a variable in my XQuery ("external" variables). In java I can do this : DynamicQueryContext dynamicContext = new DynamicQueryContext(config); dynamicContext.setParameter("inputString", someContentAsString); which I can use in the XQuery like this : declare variable $inputString external; Here is my actual code (working so far ): Dim pro As New Processor Dim co As XQueryCompiler Dim exe As XQueryExecutable Dim eval As XQueryEvaluator serializer.SetOutputStream(New FileStream("c:/my.txt", FileMode.Create, FileAccess.Write)) co = pro.NewXQueryCompiler() exe = co.Compile(xqueryfromfile) eval = exe.Load eval.Run(serializer)
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6837345 Legacy Poster: Michael Kay (mhkay)
You do this using the QueryEvaluator: eval.setExternalVariable(new QName("", "inputString"), new XdmAtomicValue("value")); (Actually, I notice that the constructor XdmAtomicValue(string) is missing from the documentation. That's an error in the documentation: the constructor does exist.) Michael Kay http://www.saxonica.com/
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6838535 Legacy Poster: NickDiamond (nickdiamond_80)
Awesome :) right after I posted my last message I discvoverd that the QueryEvaluator can be used as DynamicQueryContext, but I wasn't able to use QName correctly. I always tried to convert "string to QName" ... but now I have the solution !!! Thank you very much !!!
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6840591 Legacy Poster: NickDiamond (nickdiamond_80)
Hi, I just discoverd a new Problem with the external variables. If there is a Module-Declaration in my XQuery-File the use of external vars doesnt work. Example : declare variable $var1 external; ... blabla... works import module namespace myns="http://www.xyz.com/mynamespace" at "My_Modul.xquery"; declare variable $var1 external; ... Variable $var1 has not been declared... I don't have this problem running the (same) xquery with java. Does someone have an idea what could be the problem ? I wouldn't like to use XQuery without Modules (should be possible, but that would not be a nice solution)
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6851195 Legacy Poster: NickDiamond (nickdiamond_80)
No ideas for this problem ?? I am really not able to find a solution myself :(
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6851810 Legacy Poster: Michael Kay (mhkay)
I have not been able to reproduce this problem. The following program works fine for me: ================== using System; using System.IO; using System.Collections; using System.Xml; using System.Net; using Saxon.Api; public class Examples { public static void Main(String[] argv) { new Examples().run(); } public void run() { Console.WriteLine("Extra test case"); String mod1 = "import module namespace m2 = 'http://www.example.com/module2';" + "declare variable $v1 external;" + "m2:square($v1)"; String mod2 = "module namespace m2 = 'http://www.example.com/module2';" + "declare function m2:square($p) { $p * $p };"; Processor processor = new Processor(); XQueryCompiler compiler = processor.NewXQueryCompiler(); InlineModuleResolver resolver = new InlineModuleResolver(); resolver.AddModule(new Uri("http://www.example.com/module2"), mod2); compiler.QueryResolver = resolver; XQueryExecutable exp = compiler.Compile(mod1); XQueryEvaluator eval = exp.Load(); eval.SetExternalVariable(new QName("", "v1"), new XdmAtomicValue(3)); XdmAtomicValue result = (XdmAtomicValue)eval.EvaluateSingle(); Console.WriteLine("Result type: " + result.Value.GetType()); Console.WriteLine("Result value: " + (long)result.Value); } // A simple QueryResolver designed to show that the actual query // text can come from anywhere: in this case, the resolver maintains // a simple mapping of module URIs onto strings. public class InlineModuleResolver : IQueryResolver { private Hashtable modules = new Hashtable(); public void AddModule(Uri moduleName, String moduleText) { modules.Add(moduleName, moduleText); } public Uri[] GetModules(String moduleUri, Uri baseUri, String[] locationHints) { Uri[] result = { new Uri(moduleUri) }; return result; } public Object GetEntity(Uri absoluteUri) { return modules[absoluteUri]; } } } ============================= Please supply a more precise description of what you are doing and how it fails: preferably a complete program that I can run to demonstrate the problem. Michael Kay http://www.saxonica.com/
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6854894 Legacy Poster: NickDiamond (nickdiamond_80)
Hi, thanks for your answer. You are not using vb.net, and I can understand your code, but I am not able to translate this code (my skills in java are ok, but not in vb.net) So, here is what I have so far : At first, a XQuery : import module namespace test="http://www.bla.com/" at "MyModul.xquery"; declare variable $data external; <result> { $data } </result> vb.net Code : see code from my post (2009-03-17 11:33) plus : eval.SetExternalVariable(New QName("", "data"), New XdmAtomicValue("thisisjustanexampletext")) If I put the first line if the xquery into comments,and run it with vb.net the xquery does what it is supposed to do : <?xml version="1.0" encoding="UTF-8"?> <result>thisisjustanexampletext</result> But with the first line (the import of a module), I get : XQuery static error in #...ternal; <result> { $data }#: Variable $data has not been declared Do I have to configure the modules in vb.net before I run/compile the XQuery ? (in java there is no need for that !)
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6855495 Legacy Poster: Michael Kay (mhkay)
Yes, I was using C# rather than VB. It's testing precisely the same Saxon paths. You still haven't shown me your complete VB code in a form that I can run. Michael Kay http://www.saxonica.com/
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6855951 Legacy Poster: NickDiamond (nickdiamond_80)
there it is : XQuery as a file : import module namespace test="http://www.bla.com/" at "MyModul.xquery"; declare variable $data external; <result> { $data } </result> (I copied the MyModul.xquery to every"possible" directory) Here my vb-.net code : Imports System.IO Imports Saxon.Api Imports System Imports javax.xml.transform Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub Private Sub cmdButton1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdButton1.Click Dim xquerypath As String xquerypath = "c:/testXquery.xquery" Dim fs As New FileStream(xquerypath, FileMode.Open) Dim sr As New StreamReader(fs, System.Text.Encoding.GetEncoding("UTF-8")) Dim zeile As String = "" Dim xqueryfromfile As String = "" Do Until sr.Peek() = -1 zeile = sr.ReadLine() xqueryfromfile = xqueryfromfile & zeile & vbCrLf Loop 'using the xquery directly has the same effect ;) 'xqueryfromfile = "import module namespace test="http://www.bla.com/" at "MyModul.xquery';declare variable $data external;<result>{$data}</result>" fs.Close() sr.Close() Dim pro As New Processor Dim co As XQueryCompiler Dim exe As XQueryExecutable Dim eval As XQueryEvaluator Dim serializer As New Serializer Dim stream As New MemoryStream Dim filestream As New FileStream("c:/testoutput.xml", FileMode.Create, FileAccess.Write) serializer.SetOutputStream(filestream) Try co = pro.NewXQueryCompiler() exe = co.Compile(xqueryfromfile) eval = exe.Load eval.SetExternalVariable(New QName("", "data"), New XdmAtomicValue("thisisjustanexample")) eval.Run(serializer) Catch ex As Exception End Try filestream.Close() serializer.Close() End Sub End Class
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6859160 Legacy Poster: Michael Kay (mhkay)
You've got an empty Catch block which suppresses all errors: not a useful thing to do when you're trying to find out what's failing. The particular exception that you're suppressing is the one that says that BaseUri hasn't been set on the XQueryCompiler, which means that the relative URI for the library module can't be resolved. Also, if you're running this in a windows environment (I ran it as a console application), it's very likely you're not seeing Saxon's compile time messages, except for the last one which is returned to the application. Set the ErrorList property on the XQueryCompiler and display the contents somewhere useful if the compilation fails. The error that says the variable is undeclared is just bad error recovery from a previous error, specifically a failure during module import which you have suppressed. When I fixed the BaseUri problem the code worked fine.
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6859975 Legacy Poster: NickDiamond (nickdiamond_80)
Hi Michael, awesome again :) setting the base-uri was the missing point . In java I never used the possibilty to set the base-uri, because it did work without that (and so I never really knew what it is for). But I think that was/is only possible because my IDE (eclipse) automatically sets a base-uri (the folder of the actual project). Sorry, I did forget to paste my error-handling. I tried txtTextBox.Text = ex.StackTrace, but I was not able to get the full error message... (not important right now cause its working ;) ) Thank you very much (again) !!!!
RE: Run XQuery with vb .net - Added by Anonymous almost 16 years ago
Legacy ID: #6860293 Legacy Poster: Michael Kay (mhkay)
(not important right now cause its working ;) ) It won't stay working for ever. Add some proper error handling now, before you forget.
Please register to reply