Changes specific to .NET

Saxon on .NET is now built using version 0.36.0.11 of IKVMC. The main difference this makes is that the class library used is now the OpenJDK class library rather than the GNU Classpath library. This in turn has different licensing conditions.

There is now an option processor.SetProperty("http://saxon.sf.net/feature/preferJaxpParser", "true") whose effect is to cause Saxon to use the XML parser in the OpenJDK class library in preference to the (Microsoft) System.Xml parser. This is useful when the stylesheet or query uses the id() or idref() function when attribute types are defined in a DTD: the Microsoft XML parser does not report attribute types to the application, so these functions fail to find anything when the source document was built using this parser. Using the JAXP parser gets around this problem.

Saxon on .NET is now built and tested on .NET 2.0. It should be compatible with .NET 1.1 or .NET 3.5, but this cannot be guaranteed. Saxon is not tested on Mono, though users have reported running it successfully.

New constructors have been added to the class DomDestination, allowing new content to be attached to an existing document, document fragment, or element node.

A new method is available on the XPathCompiler class to import a schema namespace for reference within the body of the expression.

A new method Processor.WriteXdmValue(XdmValue, XmlDestination) has been added, allowing any XDM value (for example, a document node) to be written to any XmlDestination (for example, a Serializer, a Validator, or a Transformer).

The WriteTo method on XdmNode has been changed so it will write to any XmlWriter, not only an XmlTextWriter as before.

A new property MessageListener has been added to the XsltTransformer object. This allows the output of <xsl:message> instructions to be intercepted. Each call of <xsl:message> generates a document node, which is passed in the form of an XdmNode to the supplied message listener. Additional parameters indicate whether the <xsl:message> instruction specified terminate="yes", and the location in the stylesheet of the originating <xsl:message> instruction.

The XmlResolver supplied as a property of various classes including the DocumentBuilder, the XsltCompiler, the XsltTransformer, and the XQueryEvaluator, is now used not only when resolving URIs at the Saxon level (for example in calls to the doc() function or in xsl:import and xsl:include), but also by the XML parser in resolving URIs referring to external entities, including an external DTD. Note that this means it is unwise to return anything other than a Stream from the GetEntity() method, since this is the only return value that the Microsoft XmlTextReader can handle.

Extension functions (external functions) may now use System.Xml.XmlNode as an argument type, provided that the node that is actually passed in the call is a Saxon wrapper around an XmlNode. Similarly, an XmlNode may also act as the return type. This also applies to subtypes of XmlNode, and to arrays of XmlNode. However, this facility is only available when Saxon is invoked via the .NET API, not when it is invoked from the command line. Note that returning XmlNode values may be expensive if the extension function is called frequently, as new wrappers are created each time; the calling stylesheet or query should also not rely on the identity of nodes that are returned in this way.

Extension functions (external functions) may also use the types Saxon.Api.XdmValue and its Saxon-defined subtypes as an argument or return type. This facility is only available when Saxon is invoked via the .NET API, not when it is invoked from the command line.

New methods are available to allow the output from the trace() function to be directed to a specified output stream, or to be discarded.

The sample applications for .NET have been rewritten, and the test drivers for the W3C XQuery and XSLT test suites have been repackaged within a simple forms-based application called TestRunner.exe.

In previous releases the documentation stated that the SQL extension was untested on .NET. This time I tried it and found it wasn't working, probably due to the absence of JDBC drivers in the OpenJDK class library. In Saxon 9.1 I have therefore excluded the relevant classes from the .DLL build. It would make more sense on .NET to implement this extension directly over the .NET data access classes.

The tooling for creating the API documentation on .NET has changed. The NDOC tool, which was used in previous releases, is no longer maintained (or usable), while the promised Microsoft replacement, SandCastle, is unfinished and poorly documented, and I couldn't get it to work. I ended up writing my own documentation generator in XSLT, taking the C# source code and the generated apidoc.xml documentation as input. There are few things missing in the resulting HTML, for example there is little information about inherited methods, but I think that what is there is more easily accessible (it follows the Javadoc style of putting all the information about one class on one page).