Trying to use catalog resolver
Added by ian davis over 10 years ago
This is I suspect a mostly don't know what I am doing question, but how do I attach a catalog resolver to a processor in 9.5PE .net? I am not sure of how much you need to see, so I have tried to pick out the bits that I think affect what I am trying to do.
imports of: using Saxon.Api; using net.sf.saxon; using net.sf.saxon.trans; using org.apache.xml.resolver.tools;
Then create the processor and read a document.
public void run(string filename) { string filepath = Path.GetDirectoryName(Path.GetFullPath(filename)); Uri baseDir = new Uri(filepath); Processor proc = new Processor(); proc.SetProperty("http://saxon.sf.net/feature/uriResolverClass", "org.apache.xml.resolver.tools.CatalogResolver"); net.sf.saxon.trans.XmlCatalogResolver.setCatalog("resources/dtd/catalog-dita.xml", proc.Implementation, true); DocumentBuilder builder = proc.NewDocumentBuilder(); builder.BaseUri = new Uri(filepath); builder.DtdValidation = false; XdmNode rootNode = builder.Build(new Uri(Path.GetFullPath(filename))); Console.Write(rootNode.ToString()); }
which when a document is read results in:
Cannot find CatalogManager.properties
Unhandled Exception: javax.xml.parsers.FactoryConfigurationError: Provider com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl not found at java.lang.Class.newInstance0(CallerID ) at java.lang.Class.newInstance(CallerID ) at net.sf.saxon.trans.DynamicLoader.getInstance(String className, PrintStream traceOut, ClassLoader classLoader) at net.sf.saxon.Configuration.getInstance(String className, ClassLoader classLoader) at net.sf.saxon.Configuration.instantiateClassName(String propertyName, Object value, Class requiredClass) at net.sf.saxon.Configuration.setConfigurationProperty(String name, Object value) at com.saxonica.config.ProfessionalConfiguration.setConfigurationProperty(String name, Object value) at Saxon.Api.Processor.SetProperty(String name, String value)
So, clearly doing something wrong but do not know what. And why com.sun...SAXParser... I thought that had been removed from Java as org.apache.xerces.jaxp.SAXParserFactoryImpl was available and a the less buggy implementation?
Replies (17)
Please register to reply
RE: Trying to use catalog resolver - Added by Michael Kay over 10 years ago
I'm not sure we actually have a test case for using catalogs on .NET via the API, as distinct from the command line, so we'll have to look into this.
If you use the option -catalog:filename on the command line, what Saxon does internally is to call the method
XmlCatalogResolver.setCatalog(String catalog, Configuration config, boolean isTracing)
and this sets all the required system properties, as well as setting org.apache.xml.resolver.tools.ResolvingXMLReader to be the selected sourceParser and styleParser in the specified Configuration.
So you seem to be going about this the right way.
You shouldn't need the call on setProperty to set the URIResolver, because the setCatalog method does this internally.
You say the exception occurs "when a document is read" - is there more stack trace identifying what your application is doing at the point where the exception occurs?
I can't see why the sun parser is being loaded. The setCatalog() method explicitly calls
Configuration.getPlatform().setDefaultSAXParserFactory();
which on .NET should call
System.setProperty("javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl");
which should ensure that when the catalog resolver asks for the platform default parser, it gets the Apache one.
We'll look into it.
RE: Trying to use catalog resolver - Added by Michael Kay over 10 years ago
Could you try reversing the order of these two lines?
proc.SetProperty("http://saxon.sf.net/feature/uriResolverClass", "org.apache.xml.resolver.tools.CatalogResolver"); net.sf.saxon.trans.XmlCatalogResolver.setCatalog("resources/dtd/catalog-dita.xml", proc.Implementation, true);
I think it might be that the setProperty() is causing the catalog resolver to be initialized before the setCatalog() call gets a chance to set the relevant system properties that affect its behaviour.
Michael Kay Saxonica
RE: Trying to use catalog resolver - Added by ian davis over 10 years ago
Hi Mike
Thanks for the comments.
swapping the statements is one step forward, it is trying to find the correct version, but the error is the same
Unhandled Exception: javax.xml.parsers.FactoryConfigurationError: Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found at java.lang.Class.newInstance0(CallerID ) at java.lang.Class.newInstance(CallerID ) at net.sf.saxon.trans.DynamicLoader.getInstance(String className, ClassLoader classLoader) at net.sf.saxon.Configuration.makeURIResolver(String className) at net.sf.saxon.trans.XmlCatalogResolver.setCatalog(String catalog, Configuration config, Boolean isTracing)
After reading your comments I removed the setProperty as got the same response which as you suggest would indicate this is superfluous.
The rest of the stack would not shed much light I don't think it is the simple structure I have to get to the run() function above. at xmlManager.run(String filename) at Core.CoreMain..ctor() at pgMain.Main()
One further question. I have a PE license, but I do not think I am using the licensed version so I guess this would drop to HE. Is the functionality the same in both versions? (I have not set anything to pick up the license, do not have SAXON_HOME set, and have moved IKVM + saxon dlls into the VS output folder.)
RE: Trying to use catalog resolver - Added by T Hata almost 10 years ago
Any update on this issue? I'm having the same exception on ASP.NET 4.0 + Saxon-EE 9.6.0.4.
RE: Trying to use catalog resolver - Added by T Hata almost 10 years ago
My test code is pretty simple as ian's.
{
Processor proc = new Processor();
net.sf.saxon.trans.XmlCatalogResolver.setCatalog("http://example.com/catalog.xml", proc.Implementation, true);
DocumentBuilder builder = proc.NewDocumentBuilder();
}
On ASP.NET:
[FactoryConfigurationError: Provider org.apache.xerces.jaxp.SAXParserFactoryImpl not found] IKVM.NativeCode.sun.misc.Unsafe.throwException(Object thisUnsafe, Exception x) +33 sun.misc.Unsafe.throwException(Exception t) +37 java.lang.Class.newInstance0(CallerID ) +744 java.lang.Class.newInstance(CallerID ) +104 net.sf.saxon.trans.DynamicLoader.getInstance(String className, ClassLoader classLoader) +180 net.sf.saxon.Configuration.makeURIResolver(String className) +73 net.sf.saxon.trans.XmlCatalogResolver.setCatalog(String catalog, Configuration config, Boolean isTracing) +237 _Default.Page_Load(Object sender, EventArgs e)
For testing purposes, I copied the same code snippet into a console app Main(). The exception didn't happen at setCatalog(). But at NewDocumentBuilder() in the next line,
Unhandled Exception: System.InvalidCastException: Unable to cast object of type 'org.apache.xml.resolver.tools.CatalogResolver' to type 'net.sf.saxon.dotnet.DotNetURIResolver'. at Saxon.Api.Processor.get_XmlResolver() at Saxon.Api.Processor.NewDocumentBuilder() at ConsoleApplication1.Program.Main(String[] args)
I'm new to .NET and Saxon, so stuck here.
RE: Trying to use catalog resolver - Added by O'Neil Delpratt almost 10 years ago
Hi thanks reporting the issue you have found. We are currently investigating it so we will respond shortly.
RE: Trying to use catalog resolver - Added by O'Neil Delpratt almost 10 years ago
Hi,
I have managed to track down the cause to the problems reported.
In regards to the SAXParserFactoryImpl exception I have created the bug issue #2305 to keep track of the solution and reference The other problem relates to the class cast exception on the XmlResolver which has been detailed in the bug issue #2306.
RE: Trying to use catalog resolver - Added by O'Neil Delpratt almost 10 years ago
Hi,
Just to say that both bugs have been fixed and committed to subversion. The patch will be available in the next maintenance release.
RE: Trying to use catalog resolver - Added by T Hata almost 10 years ago
Really happy to hear that. Thank you, O'Neil.
RE: Trying to use catalog resolver - Added by ian davis almost 10 years ago
Thanks very much O'Neil Do you have a release schedule at all, or is it keep a watch on the website?
On 04/02/2015 12:19, Saxonica Developer Community wrote:
RE: Trying to use catalog resolver - Added by O'Neil Delpratt almost 10 years ago
Hi Ian,
We generally don't set firm deadlines. Nevertheless there are fair number of fixed bugs issues since the last maintenance, so we expect there to be another release soon. It might be good for you to subscribe as watcher to our releae announcements news at: https://saxonica.plan.io/news/1
Also we send notifications on the saxon mailing list: saxon-help@lists.sourceforge.net
RE: Trying to use catalog resolver - Added by T Hata over 9 years ago
On 9.6.0.5, the original exceptions do not happen. Thanks for the fix. However,
Uri uri = new Uri( "p:\\test.xsl" ); Processor proc = new Processor(); net.sf.saxon.trans.XmlCatalogResolver.setCatalog( "http://example.com/catalog.xml", proc.Implementation, true ); XsltCompiler compiler = proc.NewXsltCompiler(); XsltExecutable exec = compiler.Compile( uri );ends up with another exception:
Unhandled Exception: System.InvalidCastException: Unable to cast object of type 'org.apache.xml.resolver.tools.CatalogResolver' to type 'net.sf.saxon.dotnet.DotNetURIResolver'. at Saxon.Api.XsltCompiler.get_XmlResolver() at Saxon.Api.XsltCompiler.Compile(Uri uri)To get it work, do we need additional setProperty() or something?
RE: Trying to use catalog resolver - Added by O'Neil Delpratt over 9 years ago
This is indeed a bug which has now been fixed and committed to subversion ready for the next maintenance release. See comment: https://saxonica.plan.io/issues/2306#note-6
As a workaround the following should work. Here we set a default XmlUrlResolver on the processor before the NewXsltCompiler method is called:
... XmlUrlResolver resolver = new XmlUrlResolver; proc.XmlResolver = resolver; XsltCompiler compiler = proc.NewXsltCompiler(); ...
RE: Trying to use catalog resolver - Added by T Hata over 9 years ago
Thank you for fixing the underlying issue.
I'll try the workaround. Which one of the following presumptions is true?
- With the workaround, the catalog resolver is expected to fully work.
- The workaround only avoids the exception; the catalog resolver will not fully work until the next maintenance release.
RE: Trying to use catalog resolver - Added by Michael Kay over 9 years ago
Sorry to drop the ball on this.
The workaround prevents the exception, but it does not enable the catalog resolver to be used on this path: at least not fully. To work fully, the resolver must handle both (a) XML-level references, e.g. to DTDs and external entities, and (b) XSLT-level references, e.g. xsl:include and xsl:import.
We've been studying the code, and it seems that:
-
Compile(Uri) always invokes the Microsoft .NET XMLReader. This will never under any circumstances use a catalog resolver to resolve XML-level references, but I think that once the exception is avoided, it may well use the catalog resolver to resolve XSLT-level references.
-
Compile(Stream) by contrast invokes the Apache XMLReader. This should work happily with the catalog resolver to resolve XML-level references.
We can't at present see any good reason why Compile(Uri) should not work in the same way as Compile(Stream). You might like to try using the latter interface, and seeing if this works.
RE: Trying to use catalog resolver - Added by T Hata over 9 years ago
I modified my code to do setCatalog() and then Compile(Stream) instead of Compile(Uri)... Now the catalog resolver is working. Thank you so much!
Please register to reply