Saxon-HE 10.9.0在.NET中调用unparsed-text()加载HTTPS URI报错求助
解决Saxon-HE 10.9.0在.NET中使用unparsed-text()加载HTTPS资源的错误
问题描述
在.NET应用中使用Saxon-HE 10.9.0执行XSLT转换时,通过unparsed-text()函数加载HTTPS资源(示例为jQuery的CDN链接):
<xsl:value-of select="unparsed-text('https://code.jquery.com/jquery-3.5.1.min.js')"/>
XMLSpy中运行该XSLT可正常生成输出,但.NET程序运行时抛出错误:
Cannot convert absolute URI https://code.jquery.com/jquery-3.5.1.min.js to URL at Saxon.Api.Xslt30Transformer.ApplyTemplates(Stream input, XmlDestination destination)
已添加IKVM的HTTPS协议配置到App.config,但问题未解决:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="ikvm:https.protocols" value="TLSv1,TLSv1.1,TLSv1.2" /> </appSettings> <connectionStrings> <add key="ikvm:https.protocols" value="TLSv1,TLSv1.1,TLSv1.2" /> </connectionStrings> </configuration>
解决方案
1. 自定义URIResolver处理HTTPS请求
Saxon的默认URI解析器在IKVM环境下对HTTPS的支持有限,自定义一个URIResolver手动处理远程HTTPS请求:
using Saxon.Api; using System.IO; using System.Net; public class HttpsUriResolver : UriResolver { public override XdmValue Resolve(Uri absoluteUri, string baseUri, XPathContext context) { if (absoluteUri.Scheme == Uri.UriSchemeHttps) { // 强制设置TLS 1.2协议 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; using (var client = new WebClient()) { string content = client.DownloadString(absoluteUri); return new XdmAtomicValue(content); } } // 其他协议沿用默认解析逻辑 return base.Resolve(absoluteUri, baseUri, context); } }
初始化Saxon转换器时注册该解析器:
var processor = new Processor(); var compiler = processor.NewXsltCompiler(); var executable = compiler.Compile(new Uri("path/to/your/xslt.xsl")); var transformer = executable.Load30(); // 注册自定义URIResolver transformer.SetUriResolver(new HttpsUriResolver()); // 执行转换 var input = processor.NewDocumentBuilder().Build(new Uri("path/to/input.xml")); var output = new DomDestination(); transformer.ApplyTemplates(input, output);
2. 提前下载资源到本地再读取
如果自定义解析器仍有问题,可以先将远程JS文件下载到本地,再通过unparsed-text()读取本地路径:
修改XSLT代码:
<xsl:value-of select="unparsed-text('jquery-3.5.1.min.js')"/>
在.NET程序中先完成文件下载:
using System.Net; // 下载文件到程序运行目录 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; using (var client = new WebClient()) { client.DownloadFile("https://code.jquery.com/jquery-3.5.1.min.js", "jquery-3.5.1.min.js"); } // 后续执行Saxon转换逻辑...
3. 优化IKVM配置与版本兼容性
- 移除App.config中
<connectionStrings>下重复的ikvm:https.protocols配置,仅保留<appSettings>中的一份即可 - 检查Saxon-HE 10.9.0依赖的IKVM版本,尝试升级到IKVM 8.7.0及以上的稳定版本,部分旧版IKVM存在HTTPS处理的兼容性问题
内容的提问来源于stack exchange,提问作者Andrew Tyson
相关产品推荐
相关产品推荐

