Как можно сопоставить подузел в xslt в xml? - PullRequest
1 голос
/ 22 мая 2019

Я унаследовал проект, который хочет использовать 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

Ответы [ 2 ]

2 голосов
/ 22 мая 2019

Я думаю, что основная проблема заключается в том, что вы начинаете с элементов в документе 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-документ в качестве второго аргумента.

0 голосов
/ 22 мая 2019

В вашем 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>
...