如何匹配xml中xslt中的子节点?

时间:2019-05-22 08:36:12

标签: html xml xslt xslt-1.0

我继承了一个项目,该项目希望使用xslt转换一些html。匹配可以使用'/',但无法在子节点上运行

我在mozilla上找到了一些代码片段,该代码片段将xslt转换应用于mozilla上的html,代码工作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 个答案:

答案 0 :(得分:2)

我认为主要问题是,您从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

但是在HTML中使用xmlfirmenliste之类的未定义元素并在HTML DOM和XML DOM之间移动的整个方法在我的经验中遇到了麻烦。考虑将要转换的XML数据保留在HTML文档之外的单独的XML文档中,仅在XML文档上使用XSLT,并且如果将transformToFragment与拥有的HTML文档作为第二个参数。

答案 1 :(得分:0)

在您的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>