Проблема с Edge и IE11 XSLT - PullRequest
0 голосов
/ 04 мая 2020

Я столкнулся с проблемой с Edge и IE11, использующими XSLT для преобразования из HTML в XML. При преобразовании элементы, содержащие только пробелы (один или несколько), превращаются в пустой или самозакрывающийся элемент после преобразования только в Edge и IE11; Chrome и Firefox сохраняют пробелы. Это верно от XML до HTML и HTML до XML Я создал на Codepen пример проблемы с HTML до XML, которая представляет собой ультрапроблемную версию кода, чтобы с минимальным уровнем шума продемонстрировать, какой процесс я использую. https://codepen.io/akealey/pen/YzyEmpz

Запустите ручку в Chrome и Edge, и в результате Edge удалит пробел. Есть ли способ сохранить место (а)? Я прошел через все виды различных атрибутов и настроек, но ничего не работает. Преобразуемая разметка существует на веб-странице (веб-страница, которую я полностью контролирую, документ - нет).

var outStr, processor, implementationObject, transformedDocument;
// a trimmed down document all the way to the element in question
var xmlStr = '<div> </div>';
// an alternate bare bones xslt. also does not generate a space in the output
var xsltStr = '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n<xsl:output method="xml" encoding="utf-8" indent="no"/>\n<xsl:template match="/">\n<xsl:copy-of select="*" />\n</xsl:template></xsl:stylesheet>';

// create the dom parser
var domParser = new DOMParser();
// parse both xml and xslt into actual dom objects. Note xml has the xml header prepended
var xmlDoc = domParser.parseFromString('<?xml version="1.0" ?>' + xmlStr, 'text/xml');
var xsltDoc = domParser.parseFromString(xsltStr, 'text/xml');

// test what xslt processors are available. if chrome, firefox, edge - else ie11
if (typeof XSLTProcessor !== "undefined" && XSLTProcessor !== null) {
  // Chrome
  // Edge
  // Firefox
  processor = new XSLTProcessor();
  processor.importStylesheet(xsltDoc);
  //edge has the space inside xmlDoc up to this point
  transformedDocument = processor.transformToFragment(xmlDoc, document);
  // inspecting the tansformed document in Edge shows the element has no space but chrome and firefox does
} else if ('transformNode' in xmlDoc) {
  // IE11
  transformedDocument = xmlDoc.transformNode(xsltDoc);
} else {
  console.log('no transform engine found');
}

// turn the converted xml document into a string
var xmlSerializer = new XMLSerializer();
var transformResult = xmlSerializer.serializeToString(transformedDocument);
console.log(transformResult);
// In Edge .serializeToString() turns the element in to a self closing tag (as there is no content)

var hasSpace = /> <\//.test(transformResult);
console.log(hasSpace);

Ответы [ 2 ]

0 голосов
/ 05 мая 2020

В вашем коде есть ошибки в IE. transformNode не определено в IE. Вам нужно использовать new ActiveXObject('Msxml2.DOMDocument.6.0') и loadXML в IE вместо DOMParser для анализа XML. Что касается Edge, я поддерживаю ответ Мартина: примените xml:space="preserve" к элементу root, тогда он будет применяться и ко всем потомкам.

Окончательный пример кода такой, который может хорошо работать в IE и Edge (обратите внимание на //IE11 части в коде):

function textOrConsole(text, elementSelector) {
  var processorElement = document.querySelector(elementSelector);
  if (processorElement)
    processorElement.innerText = text;
  else
    console.log(text);
}

var outStr, processor, implementationObject, transformedDocument, transformResult;
// a trimmed down document all the way to the element in question
var xmlStr = '<div xml:space="preserve"><div> </div></div>';
// an alternate bare bones xslt. also does not generate a space in the output
var xsltStr = '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">\n<xsl:output method="xml" encoding="utf-8" indent="no"/>\n<xsl:template match="/">\n<xsl:copy-of select="*" />\n</xsl:template></xsl:stylesheet>';

// create the dom parser
var domParser = new DOMParser();
// parse both xml and xslt into actual dom objects. Note xml has the xml header prepended
var xmlDoc = domParser.parseFromString('<?xml version="1.0" ?>' + xmlStr, 'text/xml');
var xsltDoc = domParser.parseFromString(xsltStr, 'text/xml');

// test what xslt processors are available. if chrome, firefox, edge - else ie11
if (typeof XSLTProcessor !== "undefined" && XSLTProcessor !== null) {
  // Chrome
  // Edge
  // Firefox
  textOrConsole('XSLTProcessor (transformToFragment)', '#transform');
  processor = new XSLTProcessor();
  processor.importStylesheet(xsltDoc);
  //edge has the space inside xmlDoc up to this point
  transformedDocument = processor.transformToFragment(xmlDoc, document);
  // inspecting the tansformed document in Edge shows the element has no space but chrome and firefox does
} else if (!!window.ActiveXObject || "ActiveXObject" in window) {
  // IE11
  var docxml = new ActiveXObject('Msxml2.DOMDocument.6.0');
  docxml.loadXML(xmlStr);

  var docxsl = new ActiveXObject('Msxml2.DOMDocument.6.0');
  docxsl.loadXML(xsltStr);

  transformedDocument = docxml.transformNode(docxsl);
  textOrConsole('xmlDoc.transformNode', '#transform');
} else {
  console.log('no transform engine found');
}

// turn the converted xml document into a string
var xmlSerializer = new XMLSerializer();
if (!!window.ActiveXObject || "ActiveXObject" in window) {
  // IE11
  transformResult = transformedDocument;
} else {
  transformResult = xmlSerializer.serializeToString(transformedDocument);
}
// In Edge .serializeToString() turns the element int oa self closing tag (as there is no content)

var hasSpace = /> <\//.test(transformResult);
textOrConsole("Transformed element: " + transformResult, '#text');
textOrConsole("Has space: " + hasSpace, '#hasSpace');
<h3>Result</h3>
<span>Transform used: </span><span id="transform"></span>
<div id="text"></div>
<div id="hasSpace"></div>
</body>
0 голосов
/ 04 мая 2020

Для IE с использованием MS XML напрямую. Я думаю, вам нужно установить preserveWhiteSpace на true в любом DOMDocument перед использованием load или loadXML, так как по умолчанию это свойство имеет значение false (https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms761353 (v% 3Dvs.85) ).

Для Edge может помочь настройка <div xml:space="preserve"> </div>.

...