XSLTProcessor
XSLTProcessor 会将 XSLT 样式表转换应用于 XML 文档,并生成一个新的 XML 文档作为输出。它提供了加载 XSLT 样式表、操作 <xsl:param> 参数值以及将转换应用于文档的方法。
构造函数
XSLTProcessor()-
创建一个新的
XSLTProcessor。
实例方法
XSLTProcessor.importStylesheet()-
导入 XSLT 样式表。如果提供的节点是文档节点,您可以传入一个完整的 XSL 转换或一个 字面量结果元素转换;否则,它必须是
<xsl:stylesheet>或<xsl:transform>元素。 XSLTProcessor.transformToFragment()-
通过应用使用
XSLTProcessor.importStylesheet()函数导入的 XSLT 样式表来转换源节点。生成的文档片段的所有者文档是源节点。 XSLTProcessor.transformToDocument()-
通过应用使用
XSLTProcessor.importStylesheet()函数导入的 XSLT 样式表来转换源节点。 XSLTProcessor.setParameter()-
设置已导入的 XSLT 样式表中的参数(
<xsl:param>)值。 XSLTProcessor.getParameter()-
从 XSLT 样式表中获取参数的值。
XSLTProcessor.removeParameter()-
如果参数之前已设置,则移除该参数。这将使
XSLTProcessor使用 XSLT 样式表中指定的参数的默认值。 XSLTProcessor.clearParameters()-
从
XSLTProcessor中移除所有已设置的参数。XSLTProcessor随后将使用 XSLT 样式表中指定的默认值。 XSLTProcessor.reset()-
从
XSLTProcessor中移除所有参数和样式表。
实例属性
此接口没有属性。
示例
实例化 XSLTProcessor
async function init() {
const parser = new DOMParser();
const xsltProcessor = new XSLTProcessor();
// Load the XSLT file, example1.xsl
const xslResponse = await fetch("example1.xsl");
const xslText = await xslResponse.text();
const xslStylesheet = parser.parseFromString(xslText, "application/xml");
xsltProcessor.importStylesheet(xslStylesheet);
// process the file
// …
}
基于文档 DOM 的一部分创建 XML 文档
对于实际转换,XSLTProcessor 需要一个 XML 文档,该文档与导入的 XSL 文件结合使用以生成最终结果。XML 文档可以是使用 fetch() 加载的独立 XML 文件,也可以是现有页面的一部分。
要处理页面 DOM 的一部分,必须首先在内存中创建一个 XML 文档。假设要处理的 DOM 包含在一个 ID 为 example 的元素中,可以使用内存中 XML 文档的 Document.importNode() 方法来“克隆”该 DOM。 Document.importNode() 允许在文档之间传输 DOM 片段,在本例中是从 HTML 文档传输到 XML 文档。第一个参数引用要克隆的 DOM 节点。将第二个参数设置为“true”将克隆所有后代节点(深层克隆)。然后,可以使用 Node.appendChild() 将克隆的 DOM 插入到 XML 文档中,如下所示。
// Create a new XML document in memory
const 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
const myNode = document.getElementById("example");
const clonedNode = xmlRef.importNode(myNode, true);
// Add the cloned DOM into the XML document
xmlRef.appendChild(clonedNode);
导入样式表后,XSLTProcessor 必须执行两个方法才能进行实际转换,即 XSLTProcessor.transformToDocument() 和 XSLTProcessor.transformToFragment()。 XSLTProcessor.transformToDocument() 返回一个完整的 XML 文档,而 XSLTProcessor.transformToFragment() 返回一个文档片段,该片段可以轻松地添加到现有文档中。两者都将要转换的 XML 文档作为第一个参数。 XSLTProcessor.transformToFragment() 需要第二个参数,即生成片段的所有者文档对象。如果生成的片段将插入到当前 HTML 文档中,则传递 document 就足够了。
从字符串“XML Soup”创建 XML 文档
您可以使用 DOMParser 从 XML 字符串创建 XML 文档。
const parser = new DOMParser();
const doc = parser.parseFromString(str, "text/xml");
执行转换
const fragment = xsltProcessor.transformToFragment(xmlRef, document);
基本示例
基本示例将加载一个 XML 文件并对其应用 XSL 转换。这些是与 生成 HTML 示例中使用的相同文件。XML 文件描述了一篇文章,XSL 文件格式化信息以便显示。
XML
<?xml version="1.0"?>
<myNS:Article xmlns:myNS="http://devedge.netscape.com/2002/de">
<myNS:Title>My Article</myNS:Title>
<myNS:Authors>
<myNS:Author company="Foopy Corp.">Mr. Foo</myNS:Author>
<myNS:Author>Mr. Bar</myNS:Author>
</myNS:Authors>
<myNS:Body>
The <b>rain</b> in <u>Spain</u> stays mainly in the plains.
</myNS:Body>
</myNS:Article>
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myNS="http://devedge.netscape.com/2002/de">
<xsl:output method="html" />
<xsl:template match="/">
<html>
<head>
<title>
<xsl:value-of select="/myNS:Article/myNS:Title"/>
</title>
<style>
.myBox {margin:10px 155px 0 50px; border: 1px dotted #639ACE; padding:0 5px 0 5px;}
</style>
</head>
<body>
<p class="myBox">
<span class="title">
<xsl:value-of select="/myNS:Article/myNS:Title"/>
</span> <br />
Authors: <br />
<xsl:apply-templates select="/myNS:Article/myNS:Authors/myNS:Author"/>
</p>
<p class="myBox">
<xsl:apply-templates select="//myNS:Body"/>
</p>
</body>
</html>
</xsl:template>
<xsl:template match="myNS:Author">
-- <xsl:value-of select="." />
<xsl:if test="@company">
:: <b> <xsl:value-of select="@company" /> </b>
</xsl:if>
<br />
</xsl:template>
<xsl:template match="myNS:Body">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
该示例将 .xsl (xslStylesheet) 和 .xml (xmlDoc) 文件加载到内存中。然后导入 .xsl 文件 (xsltProcessor.importStylesheet(xslStylesheet)) 并运行转换 (xsltProcessor.transformToFragment(xmlDoc, document))。这允许在页面加载后获取数据,而无需重新加载页面。
JavaScript
async function init() {
const parser = new DOMParser();
const xsltProcessor = new XSLTProcessor();
// Load the XSLT file, example1.xsl
const xslResponse = await fetch("example1.xsl");
const xslText = await xslResponse.text();
const xslStylesheet = parser.parseFromString(xslText, "application/xml");
xsltProcessor.importStylesheet(xslStylesheet);
// Load the XML file, example1.xml
const xmlResponse = await fetch("example1.xml");
const xmlText = await xmlResponse.text();
const xmlDoc = parser.parseFromString(xmlText, "application/xml");
const fragment = xsltProcessor.transformToFragment(xmlDoc, document);
document.getElementById("example").textContent = "";
document.getElementById("example").appendChild(fragment);
}
init();
高级示例
这个高级示例根据内容对多个 div 进行排序。该示例允许多次排序内容,并在升序和降序之间交替。JavaScript 仅在第一次排序时加载 .xsl 文件,并在文件加载完成后将 xslLoaded 变量设置为 true。使用 XSLTProcessor.getParameter() 方法,代码可以确定是升序还是降序排序。如果参数为空(首次排序时,因为 XSLT 文件中没有该参数的值),则默认为升序。排序值使用 XSLTProcessor.setParameter() 设置。
XSLT 文件中有一个名为 myOrder 的参数,JavaScript 会设置它来更改排序方法。xsl:sort 元素的 order 属性可以使用 $myOrder 访问参数的值。但是,该值需要是 XPath 表达式而不是字符串,因此使用 {$myOrder}。使用 {} 会将内容评估为 XPath 表达式。
转换完成后,结果会追加到文档中,如本示例所示。
XHTML
<div id="example">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
JavaScript
let xslRef;
let xslLoaded = false;
const parser = new DOMParser();
const xsltProcessor = new XSLTProcessor();
let myDOM;
let xmlRef = document.implementation.createDocument("", "", null);
async function sort() {
if (!xslLoaded) {
const response = await fetch("example2.xsl");
const xslText = await response.text();
xslRef = parser.parseFromString(xslText, "application/xml");
xsltProcessor.importStylesheet(xslRef);
xslLoaded = true;
}
// Create a new XML document in memory
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
const myNode = document.getElementById("example");
const clonedNode = xmlRef.importNode(myNode, true);
// After cloning, we append
xmlRef.appendChild(clonedNode);
// Set the sorting parameter in the XSL file
const sortVal = xsltProcessor.getParameter(null, "myOrder");
if (sortVal === "" || sortVal === "descending") {
xsltProcessor.setParameter(null, "myOrder", "ascending");
} else {
xsltProcessor.setParameter(null, "myOrder", "descending");
}
// Initiate the transformation
const fragment = xsltProcessor.transformToFragment(xmlRef, document);
// Clear the contents
document.getElementById("example").textContent = "";
myDOM = fragment;
// Add the new content from the transformation
document.getElementById("example").appendChild(fragment);
}
XSLT
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:param name="myOrder" />
<xsl:template match="/">
<xsl:apply-templates select="/div//div">
<xsl:sort select="." data-type="number" order="{$myOrder}" />
</xsl:apply-templates>
</xsl:template>
<xsl:template match="div">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>
规范
| 规范 |
|---|
| DOM # interface-xsltprocessor |
浏览器兼容性
加载中…