解决ASP Server中XSLT转换导致UTF-16编码问题的方法
在使用ASP脚本在服务器端执行XSLT转换(如生成KML文件)时,常遇到输出XML声明强制为encoding="UTF-16"的问题。这并非源文件或样式表配置错误,而是由于transformNode方法在Windows平台上返回字符串时默认采用UTF-16编码所致。通过改用transformNodeToObject方法并将结果直接输出至HTTP响应流,即可完美解决此编码不一致问题。
背景与问题现象
在进行天气数据优化项目(如 Weather For Google Earth)时,服务端需要将远程XML数据转换为KML格式。通常做法是将XML和XSLT文件载入内存,利用DOM引擎执行转换。
假设XML输入源如下结构:
<?xml version="1.0" encoding="UTF-8"?>
<weather ver="2.0">
<dayf>
<day d="0" t="Saturday" dt="Oct 28">...</day>
</dayf>
</weather>
XSLT转换模板声明同样指定了UTF-8编码:<xsl:output method="xml" encoding="UTF-8" />。
初始代码与失败原因
开发者通常会编写如下ASP (VBScript/JScript) 代码进行转换:
// 设置输出类型为KML,声明字符集为UTF-8
Response.ContentType = "application/vnd.google-earth.kml+xml";
Response.CharSet = "UTF-8";
// 加载远程XML数据
var oXmlHttp = Server.CreateObject("MSXML2.XMLHTTP");
oXmlHttp.open("GET", url, false);
oXmlHttp.send();
var xmlDoc = Server.CreateObject("MSXML2.DOMDocument");
xmlDoc.loadXML(oXmlHttp.responseText);
// 加载本地XSLT样式表
var xslDoc = Server.CreateObject("Microsoft.XMLDOM");
xslDoc.async = false;
xslDoc.load(Server.MapPath("gew.xsl"));
// 【关键步骤】执行转换
Response.Write(xmlDoc.transformNode(xslDoc));
第1步:分析问题根源
尽管代码中显式声明了UTF-8,但生成的文件头部依然显示encoding="UTF-16"。其根本原因在于transformNode方法的内部机制:
- 中间变量类型限制:
transformNode方法实际上是将转换结果作为一个字符串(String)返回,然后由Response.Write输出。 - 平台默认编码:在Win32平台环境下,MSXML引擎在处理字符串流转时,默认采用
UTF-16编码。 - 覆盖声明:即使外层响应设置了UTF-8,但引擎检测到生成的原始内容实际字节序列符合UTF-16特征,因此会在输出的XML声明中自动修正为UTF-16以保证内容可读性,导致前端解析混乱。
第2步:实施解决方案
要彻底解决此问题,需要绕过“字符串中间层”,直接将转换后的XML节点树写入输出流。
- 替换转换方法:放弃使用返回字符串的
transformNode,改用transformNodeToObject。 - 指定输出目标:将转换结果的第二个参数设为
Response对象,使引擎直接把序列化后的XML数据推送到HTTP响应缓冲区。
修改后的核心代码段如下:
// 保持原有的Header设置不变
Response.ContentType = "application/vnd.google-earth.kml+xml";
Response.CharSet = "UTF-8";
// ... 前面加载XML和XSL的代码保持不变 ...
// 【修正后】直接转换到Response对象
xmlDoc.transformNodeToObject(xslDoc, Response);
总结
transformNode与transformNodeToObject的区别在于前者操作的是字符串变量,后者操作的是DOM对象或流。在ASP服务端的XML/XSLT转换场景中,只要涉及中文或其他非ASCII字符,且对编码有严格要求,优先选择transformNodeToObject能避免绝大多数的编码损坏问题。
以上就是ASP中解决XSLT转换编码问题的详细内容,更多关于服务器端XML数据处理与编码规范的文章请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













