我正在努力解决在客户端XSL转换时我只遇到Internet Explorer 10和11的问题。我的目标是转换包含HTML标记<pre>...</pre>
的给定XML字符串,以便准备格式化的输出。
Carriagereturn-linefeed字符(&#34; \ n&#34;)在转换过程中迷失了(顺便说一句:即使将它们包装到CDATA容器中),在转换后输出的更令人困惑的是输出在任意位置包含其他cr / lfs。
仅在IE 10/11中发生。 Chrome或Firefox没有这样的问题,也没有Edge!
我知道IE中的XSLT与其他浏览器的处理方式不同,我在我的例子中已经考虑过两种不同的选择,但两者都会产生相同的输出。
请查看我的以下HTML代码段(只需在IE和Chrome / FF中试用,您就会明白我的意思......):
<!DOCTYPE html>
<html>
<head>
<title>Test maker</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<script type="text/javascript">
var xml = "<Actions><action><html><body><pre xml:space=\"preserve\">"
+ "\nThis line is not split and it ends with a dedicated cr-lf.\n"
+ "This is a new line. It also continues until the full-stop, then has a cr-lf.\n"
+ "This is the third and therewith the last line.\n</pre></body></html></action></Actions>";
var xsl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">"
+ "<xsl:preserve-space elements=\"*\"/>"
+ "<xsl:template match=\"/\"><Actions><xsl:for-each select=\"//action\"><action><description><xsl:apply-templates select=\"html/*\" />"
+ "</description></action></xsl:for-each></Actions></xsl:template><xsl:template match=\"html//pre\"><xsl:text><code></xsl:text>"
+ "<xsl:apply-templates select=\"node()\"/><xsl:text></code></xsl:text></xsl:template>"
+ "<xsl:template match=\"text()\"><xsl:value-of select=\".\"/></xsl:template></xsl:stylesheet>";
function applyAdapterRule(odtaDocument, ruleData, alt) {
if (odtaDocument && ruleData) {
var result = null;
if (window.ActiveXObject || "ActiveXObject" in window) { // IE
//IE9 won't recognize the proper codepage
odtaDocument.charset = "UTF-8";
odtaDocument.characterSet = "UTF-8";
odtaDocument.preserveWhiteSpace = true;
switch(alt) {
case 1:
var srcTree = new ActiveXObject("Msxml2.DOMDocument.6.0");
srcTree.async=false;
srcTree.preserveWhiteSpace = true;
srcTree.load(odtaDocument);
var xslDoc = new ActiveXObject("Msxml2.DOMDocument.6.0");
xslDoc.async = false;
xslDoc.preserveWhiteSpace = true;
xslDoc.load(ruleData);
return srcTree.transformNode(xslDoc);
case 2:
var xslt = new ActiveXObject("Msxml2.XSLTemplate.6.0");
var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument.6.0");
xslDoc.async = false;
xslDoc.preserveWhiteSpace = true;
xslDoc.load(ruleData);
xslt.stylesheet = xslDoc;
var xslProc = xslt.createProcessor();
xslProc.input = odtaDocument;
xslProc.transform();
return xslProc.output;
}
} else if (document.implementation && document.implementation.createDocument) { // Chrome, Mozilla
xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(ruleData);
resultDocument = xsltProcessor.transformToDocument(odtaDocument);
return resultDocument;
}
}
};
function do_it(alternative) {
var rule = $.parseXML(xsl);
var new_xml = "";
var tempDoc = $.parseXML(xml);
// tempDoc.preserveWhiteSpace = true;
tempDoc = applyAdapterRule(tempDoc, rule, alternative);
if (typeof tempDoc === "string") {
new_xml = tempDoc; // IE
} else {
new_xml = new XMLSerializer().serializeToString(tempDoc); // Chrome, Mozilla
}
$("#out").replaceWith("<pre>"+new_xml+"</pre>");
};
</script>
</head>
<body>
<button onclick="javascript:do_it(1);">Test 1</button>
<button onclick="javascript:do_it(2);">Test 2</button>
<div><div id="out">See what happens...</div></div>
</body>
</html>
&#13;
在IE案例中,我的XSL转换还有什么问题吗?
/编辑:
从上面的示例中,我希望得到以下输出(我从Chrome和Firefox获得):
然而,使用我的IE11,无论是按第一个还是第二个按钮(即我是执行案例1还是案例2分支),我都会得到此输出:
答案 0 :(得分:0)
对于IE,我建议直接使用MSXML API,而不是将JQuery与MSXML API混合使用。使用http://home.arcor.de/martin.honnen/xslt/test2016051202.html中的代码,它基本上将您的xml
和xsl
字符串加载为
var xml = "<Actions><action><html><body><pre xml:space=\"preserve\">"
+ "\nThis line is not split and it ends with a dedicated ctrl-lf.\n"
+ "This is a new line. It also continues until the full-stop, then has a ctrl-lf.\n"
+ "This is the third and therewith the last line.\n<\/pre><\/body><\/html><\/action><\/Actions>";
var xsl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">"
+ "<xsl:preserve-space elements=\"*\"/>"
+ "<xsl:template match=\"/\"><Actions><xsl:for-each select=\"//action\"><action><description><xsl:apply-templates select=\"html/*\" />"
+ "<\/description><\/action><\/xsl:for-each><\/Actions><\/xsl:template><xsl:template match=\"html//pre\"><xsl:text><code><\/xsl:text>"
+ "<xsl:apply-templates select=\"node()\"/><xsl:text></code><\/xsl:text><\/xsl:template>"
+ "<xsl:template match=\"text()\"><xsl:value-of select=\".\"/><\/xsl:template><\/xsl:stylesheet>";
function test1() {
if (typeof DOMParser != 'undefined' && typeof XSLTProcessor != 'undefined') {
var xmlDoc = new DOMParser().parseFromString(xml, 'application/xml');
var sheet = new DOMParser().parseFromString(xsl, 'application/xml');
var proc = new XSLTProcessor();
proc.importStylesheet(sheet);
var resultDoc = proc.transformToDocument(xmlDoc);
var result = new XMLSerializer().serializeToString(resultDoc);
var pre = document.createElement('pre');
pre.textContent = result;
document.getElementById('test1').appendChild(pre);
}
else {
try {
var xmlDoc = new ActiveXObject('Msxml2.DOMDocument.6.0');
xmlDoc.loadXML(xml);
var sheet = new ActiveXObject('Msxml2.DOMDocument.6.0');
sheet.loadXML(xsl);
var result = xmlDoc.transformNode(sheet);
var pre = document.createElement('pre');
pre.textContent = result;
document.getElementById('test1').appendChild(pre);
}
catch (e) {
console.log(e);
throw e;
}
}
}
window.onload = function() {
test1();
}
转换结果保留了原始换行符:
<?xml version="1.0"?><Actions><action><description><code>
This line is not split and it ends with a dedicated ctrl-lf.
This is a new line. It also continues until the full-stop, then has a ctrl-lf.
This is the third and therewith the last line.
</code></description></action></Actions>
答案 1 :(得分:0)
因此,当我使用xmlDoc.loadXML(xml)
替换方法xmlDoc.load(xmlObj)
时,代码如下所示:
var xml = "<Actions><action><html><body><pre xml:space=\"preserve\">"
+ "\nThis line is not split and it ends with a dedicated ctrl-lf.\n"
+ "This is a new line. It also continues until the full-stop, then has a ctrl-lf.\n"
+ "This is the third and therewith the last line.\n<\/pre><\/body><\/html><\/action><\/Actions>";
var xsl = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+ "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">"
+ "<xsl:preserve-space elements=\"*\"/>"
+ "<xsl:template match=\"/\"><Actions><xsl:for-each select=\"//action\"><action><description><xsl:apply-templates select=\"html/*\" />"
+ "<\/description><\/action><\/xsl:for-each><\/Actions><\/xsl:template><xsl:template match=\"html//pre\"><xsl:text><code><\/xsl:text>"
+ "<xsl:apply-templates select=\"node()\"/><xsl:text></code><\/xsl:text><\/xsl:template>"
+ "<xsl:template match=\"text()\"><xsl:value-of select=\".\"/><\/xsl:template><\/xsl:stylesheet>";
function test1() {
if (typeof DOMParser != 'undefined' && typeof XSLTProcessor != 'undefined') {
var xmlDoc = new DOMParser().parseFromString(xml, 'application/xml');
var sheet = new DOMParser().parseFromString(xsl, 'application/xml');
var proc = new XSLTProcessor();
proc.importStylesheet(sheet);
var resultDoc = proc.transformToDocument(xmlDoc);
var result = new XMLSerializer().serializeToString(resultDoc);
var pre = document.createElement('pre');
pre.textContent = result;
document.getElementById('test1').appendChild(pre);
}
else {
try {
var xmlDoc = new ActiveXObject('Msxml2.DOMDocument.6.0');
var xmlObj = $.parseXML(xml); //convert XML String to XML Object
xmlDoc.load(xmlObj); //use load() instead of loadXML()
var sheet = new ActiveXObject('Msxml2.DOMDocument.6.0');
sheet.loadXML(xsl);
var result = xmlDoc.transformNode(sheet);
var pre = document.createElement('pre');
pre.textContent = result;
document.getElementById('test1').appendChild(pre);
}
catch (e) {
console.log(e);
throw e;
}
}
}
window.onload = function() {
test1();
}
,结果输出为:
<?xml version="1.0"?><Actions><action><description><code>This line is not split and it ends with a dedicated
ctrl-lf. This is a new line. It also continues until the full-stop, then has a
ctrl-lf. This is the third and therewith the last line.
</code></description></action></Actions>