Я унаследовал проект, который хочет использовать xslt для преобразования некоторого html. Сопоставление работает с '/', но я не могу заставить его работать на подузле
Я нашел фрагмент кода в Mozilla, который применяет преобразование xslt в html в Mozilla, код работает https://developer.mozilla.org/en-US/docs/Web/XSLT/XSLT_JS_interface_in_Gecko/Advanced_Example. Проблема в том, что я не могу сопоставить шаблон узла "firmenliste"
Что я использую:
var xslRef;
var xslloaded = false;
var xsltProcessor = new XSLTProcessor();
var myDOM;
var xmlRef = document.implementation.createDocument("", "", null);
p = new XMLHttpRequest();
p.open("GET", "xsl/FirmenListe.xsl",false);
p.send(null);
xslRef = p.responseXML;
xsltProcessor.importStylesheet(xslRef);
xmlRef = document.implementation.createDocument("", "", null);
// we want to move a part of the DOM from an HTML document to an XML document.
// importNode is used to clone the nodes we want to process via XSLT - true makes it do a deep clone
var myNode = document.getElementById("example");
var clonedNode = xmlRef.importNode(myNode, true);
// after cloning, we append
xmlRef.appendChild(clonedNode);
var fragment = xsltProcessor.transformToFragment(xmlRef, document);
// clear the contents
document.getElementById("example").innerHTML = "";
myDOM = fragment;
// add the new content from the transformation
document.getElementById("example").appendChild(fragment)
Соответствующие html и xslt выглядят так:
<xml id="Data">
<data id="example" xmlns:dt="urn:schemas-microsoft-com:datatypes">
<firmenliste></firmenliste>
</data>
</xml>
<?xml version ='1.0'?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>
<xsl:template match="/">
b
<xsl:apply-templates select="firmenliste"/>
</xsl:template>
<xsl:template match="firmenliste">
A
</xsl:template>
</xsl:stylesheet>
Результат должен быть
<xml id="Data">
<data id="example" xmlns:dt="urn:schemas-microsoft-com:datatypes">
bA
</data>
</xml>
Но то, что я получаю
<xml id="Data">
<data id="example" xmlns:dt="urn:schemas-microsoft-com:datatypes">
b
</data>
</xml>
Обновлено: проблема воспроизводится в https://next.plnkr.co/edit/Yvc59BPQmI1PHlSy?open=lib%2Fscript.js&preview.
К сожалению, это не решает проблему
Итак, ваш HTML-документ содержит элементы с именами xml
, data
и firmenliste
? Являются ли эти определенные элементы HTML в вашем представлении? И если вы только извлечете и клонируете элемент data
с помощью id="example"
, а затем поместите его в новый документ, дерево, которое видит XSLT, определенно не будет содержать элемент xml
. На что следует обратить внимание при попытке переместить узлы из HTML <--> XML с XSLT между ними, например, в случае имен элементов, начните с отладки того, как выглядит console.log(xmlRef)
, прежде чем передать его методу преобразования.
Я думаю, что основная проблема заключается в том, что вы начинаете с элементов в документе HTML DOM, которые, начиная с HTML5, по определению находятся в пространстве имен XHTML http://www.w3.org/1999/xhtml
, а затем клонируете и копируете их в документ XML, где они сохраняют свое пространство имен, но где в XSLT/XPath путь или шаблон сопоставления, например firmenliste
, выбирает или сопоставляет элементы с этим именем ни в одном пространстве имен, ни в пространстве имен XHTML.
В вашем xslt при сопоставлении корневого узла с «/» вам нужно указать весь xPath для соответствия <firmenliste>
в <xsl:apply-templates>
Попробуйте то же самое, заменив строку <xsl:apply-templates select="firmenliste"/>
с <xsl:apply-templates select="/xml/data/firmenliste"/>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
b
<xsl:apply-templates select="/xml/data/firmenliste" />
</xsl:template>
<xsl:template match="firmenliste">
A
</xsl:template>
</xsl:stylesheet>
Какой результат вы получаете?
html <xml id="Data"> <data id="example" xmlns:dt="urn:schemas-microsoft-com:datatypes"> b </data> </xml>
Проверьте демонстрацию здесь: xsltfiddle.liberty-development.net/gWvjQfK Если она по-прежнему не работает, вам необходимо указать полный и оптимальный исходный код и файл xslt.
Я создал plunkr, который может воспроизвести проблему: next.plnkr.co/edit/…
Я думаю, что основная проблема заключается в том, что вы начинаете с элементов в документе HTML DOM, которые, начиная с HTML5, по определению находятся в пространстве имен XHTML http://www.w3.org/1999/xhtml
, а затем клонируете и копируете их в документ XML, где они сохраняют свое пространство имен, но где в XSLT/XPath путь или шаблон сопоставления, такой как firmenliste
, выбирает или сопоставляет элементы с этим именем в нет пространства имен, а не в пространстве имен XHTML.
Итак, используя
<xsl:template match="/">
b
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="xhtml:firmenliste" xmlns:xhtml="http://www.w3.org/1999/xhtml">
A
</xsl:template>
вместо этого решит эту проблему: https://next.plnkr.co/edit/tsB9qwCafLodg8Rz?open=lib%2Fscript.js&preview
Но весь подход с использованием неопределенных элементов, таких как xml
или firmenliste
в HTML, и перемещение между HTML DOM и XML DOM вызывает проблемы, по моему опыту. Подумайте о том, чтобы хранить XML-данные, которые вы хотите преобразовать, вне HTML-документа, в отдельном XML-документе, использовать XSLT только для XML-документов и использовать результат преобразования только для вставки в HTML DOM, если вы использовали transformToFragment
с владельцем HTML-документа. в качестве второго аргумента.
попробуйте с <xsl:apply-templates select="node()"/>