如何在Saxon引擎的XSLT中通过.NET/Java实现HTTP POST请求
.NET 实现方案
以下是基于Saxon .NET版本的正确XSLT代码,修复了命名空间、异步处理和方法调用的问题:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:net="clitype:System.Net.Http" xmlns:encoding="clitype:System.Text.Encoding" xmlns:task="clitype:System.Threading.Tasks.Task" exclude-result-prefixes="net encoding task"> <xsl:template match="/"> <!-- 定义API端点和Payload --> <xsl:variable name="url" select="'https://httpbin.org/post'" /> <!-- 替换为实际XML数据的一部分 --> <xsl:variable name="payload" select="json-to-xml(/*) => xml-to-json()" /> <!-- 实例化HttpClient --> <xsl:variable name="client" select="net:HttpClient()" /> <!-- 创建StringContent --> <xsl:variable name="utf8" select="encoding:UTF8()" /> <xsl:variable name="content" select="net:StringContent($payload, $utf8, 'application/json')" /> <!-- 发送POST请求(同步获取异步结果) --> <xsl:variable name="responseTask" select="net:PostAsync($client, $url, $content)" /> <xsl:variable name="response" select="task:Result($responseTask)" /> <!-- 读取响应内容(同步获取异步结果) --> <xsl:variable name="contentTask" select="net:ReadAsStringAsync(net:Content($response))" /> <xsl:variable name="responseBody" select="task:Result($contentTask)" /> <!-- 输出响应 --> <xsl:message terminate="no">Response Body: <xsl:value-of select="$responseBody" /></xsl:message> </xsl:template> </xsl:stylesheet>
关键修复说明:
- 命名空间使用
clitype:前缀而非clitype=,这是Saxon调用.NET类型的正确语法 - 异步方法(
PostAsync/ReadAsStringAsync)返回Task对象,必须通过task:Result()同步获取结果,匹配XSLT的同步执行模型 - 实例方法调用需以实例对象作为第一个参数(如
net:PostAsync($client, $url, $content)),而非直接通过类型调用 - 静态属性(如
Encoding.UTF8)在Saxon中通过无参函数调用获取(encoding:UTF8())
Java 实现方案
如果使用Saxon Java版本,可调用Java 11+内置的HttpClient实现,无需额外依赖:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="3.0" xmlns:java="http://saxon.sf.net/java-type" exclude-result-prefixes="java"> <xsl:template match="/"> <!-- 定义API端点和Payload --> <xsl:variable name="url" select="'https://httpbin.org/post'" /> <!-- 替换为实际XML数据的一部分 --> <xsl:variable name="payload" select="json-to-xml(/*) => xml-to-json()" /> <!-- 创建HttpClient和请求体 --> <xsl:variable name="client" select="java:new('java.net.http.HttpClient')" /> <xsl:variable name="requestBody" select="java:new('java.net.http.HttpRequest$BodyPublishers', 'ofString', $payload)" /> <!-- 构建POST请求 --> <xsl:variable name="requestBuilder" select="java:new('java.net.http.HttpRequest$Builder', java:new('java.net.URI', $url))" /> <xsl:variable name="request" select="java:POST($requestBuilder) => java:header('Content-Type', 'application/json') => java:body($requestBody) => java:build()" /> <!-- 发送请求并获取响应 --> <xsl:variable name="response" select="java:send($client, $request, java:new('java.net.http.HttpResponse$BodyHandlers', 'ofString'))" /> <!-- 读取响应内容 --> <xsl:variable name="responseBody" select="java:body($response)" /> <!-- 输出响应 --> <xsl:message terminate="no">Response Body: <xsl:value-of select="$responseBody" /></xsl:message> </xsl:template> </xsl:stylesheet>
关键说明:
- 使用Saxon Java扩展命名空间
http://saxon.sf.net/java-type调用原生Java类 - 通过
java:new()实例化类,静态方法调用需指定类名(如java:POST($requestBuilder)) - Java 11+的
HttpClient为内置类,无需额外添加依赖,符合"无法添加额外库"的要求 - 可直接将XML节点转换为JSON/字符串作为Payload,替换示例中的
$payload即可
内容的提问来源于stack exchange,提问作者Zor
相关产品推荐
相关产品推荐

