Saxon .NET 自定义元素
Saxon .NET custom elements
我在 .NET 中使用 Saxon 8.9 并想创建一个自定义元素。这个(诚然是旧的)版本的 Saxon 的文档对此功能非常模糊,并且似乎暗示它根本不可能或只是不在 .NET 中。
谁能更深入地了解这是否可行?
更新:
在 Michael 的快速更新之后,我再次尝试了这个。
- 我创建了一个实现 ExtensionElementFactory
的 CustomElementFactory class
- 在样式表中,我添加了一个扩展元素前缀并将其与一个名称空间相关联,该名称空间的 uri 以斜线结尾,后跟 CustomElementFactory 的全名
- 将元素添加到我的样式表中。
这会导致错误 XTDE1450 "Unknown extension element"。
我什至尝试获取旧的 sql 扩展 java,使用 IKVM 转换为 dll,但它也没有用。
新版本的文档讨论了在处理器配置中注册命名空间,但 setExtensionElementNamespace 在此旧版本中不存在。
我必须使用 8.9,因为这是我们产品使用的版本,升级并不可行。
感谢所有帮助。
"custom element" 我猜你的意思是 XSLT 扩展指令(或扩展元素,具体取决于你使用的规范版本)。
如果我没记错的话,这些年来 API 的 API 并没有太大变化,但是用这么旧的版本做新事情肯定看起来很奇怪,更不用说期待帮助了。
我不记得曾经测试过可以在 .NET 上实现,但理论上应该是可能的。但是,您需要忍受接口是为 Java 而不是 C# 设计的事实。 Saxon on .NET 使用的 IKVM 技术不仅可以从 C# 调用 Java,反之亦然,而且还可以使用 C# 实现实现 Java 接口,或者覆盖 Java 方法与 C# 方法,甚至在混合代码库上使用 Visual Studio 调试器。所以我不能说这很容易,但我有理由相信这应该是可能的。
这里缺少的 link 是如何让 classloader 解析 ExtensionElementFactory。
命名空间声明中ExtensionElementFactory的全名class需要额外的"cli."前缀,例如myBiz.saxon.extensions.customExtensionElementFactory 实际上有命名空间:
xmlns:myBiz="http://myBiz.com/extensions/cli.myBiz.saxon.extensions.customExtensionElementFactory"
当工厂位于不同的引用库中时,您需要确保在 class 加载程序尝试解析它之前已加载此库。这可以使用此处描述的 GC.KeepAlive 方法来实现:IKVM ClassLoader 或通过其他方式调用它。重要的是要注意仅将库作为参考是不够的,它需要 'loaded' 才能让 ClassLoader 解析它。
或者,您可以创建自定义类加载器(实现 java.lang.ClassLoader)并将其注册到处理器:
processor.Implementation.setClassLoader(new customClassLoader());
我在 .NET 中使用 Saxon 8.9 并想创建一个自定义元素。这个(诚然是旧的)版本的 Saxon 的文档对此功能非常模糊,并且似乎暗示它根本不可能或只是不在 .NET 中。 谁能更深入地了解这是否可行?
更新: 在 Michael 的快速更新之后,我再次尝试了这个。
- 我创建了一个实现 ExtensionElementFactory 的 CustomElementFactory class
- 在样式表中,我添加了一个扩展元素前缀并将其与一个名称空间相关联,该名称空间的 uri 以斜线结尾,后跟 CustomElementFactory 的全名
- 将元素添加到我的样式表中。
这会导致错误 XTDE1450 "Unknown extension element"。 我什至尝试获取旧的 sql 扩展 java,使用 IKVM 转换为 dll,但它也没有用。
新版本的文档讨论了在处理器配置中注册命名空间,但 setExtensionElementNamespace 在此旧版本中不存在。 我必须使用 8.9,因为这是我们产品使用的版本,升级并不可行。
感谢所有帮助。
"custom element" 我猜你的意思是 XSLT 扩展指令(或扩展元素,具体取决于你使用的规范版本)。
如果我没记错的话,这些年来 API 的 API 并没有太大变化,但是用这么旧的版本做新事情肯定看起来很奇怪,更不用说期待帮助了。
我不记得曾经测试过可以在 .NET 上实现,但理论上应该是可能的。但是,您需要忍受接口是为 Java 而不是 C# 设计的事实。 Saxon on .NET 使用的 IKVM 技术不仅可以从 C# 调用 Java,反之亦然,而且还可以使用 C# 实现实现 Java 接口,或者覆盖 Java 方法与 C# 方法,甚至在混合代码库上使用 Visual Studio 调试器。所以我不能说这很容易,但我有理由相信这应该是可能的。
这里缺少的 link 是如何让 classloader 解析 ExtensionElementFactory。
命名空间声明中ExtensionElementFactory的全名class需要额外的"cli."前缀,例如myBiz.saxon.extensions.customExtensionElementFactory 实际上有命名空间:
xmlns:myBiz="http://myBiz.com/extensions/cli.myBiz.saxon.extensions.customExtensionElementFactory"
当工厂位于不同的引用库中时,您需要确保在 class 加载程序尝试解析它之前已加载此库。这可以使用此处描述的 GC.KeepAlive 方法来实现:IKVM ClassLoader 或通过其他方式调用它。重要的是要注意仅将库作为参考是不够的,它需要 'loaded' 才能让 ClassLoader 解析它。
或者,您可以创建自定义类加载器(实现 java.lang.ClassLoader)并将其注册到处理器:
processor.Implementation.setClassLoader(new customClassLoader());