使用 Fetch API 包含使用 XSLT 转换的 XML 文件

Posted

技术标签:

【中文标题】使用 Fetch API 包含使用 XSLT 转换的 XML 文件【英文标题】:Use the Fetch API to include an XML file transformed with XSLT 【发布时间】:2021-11-04 10:48:23 【问题描述】:

我有一个 xml 文件:

<?xml version="1.0" encoding="utf-8"?>                                                                     
<?xml-stylesheet href="trans.xsl" type="text/xsl"?>                                                                          
<profile>                                                                            
  <name>Leonard</name>                                                                            
  <age>99</age>                                                                             
</profile>                                                    

及其xslt 转换文件:

<?xml version="1.0" encoding="utf-8"?>                                                                          
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>                                                                                                            
    <xsl:template match="profile"> 
        <form>            
            <xsl:for-each select="child::*">                                                                     
                <label>                                                                                     
                    <xsl:value-of select="name()"/>:                                                                
                    <input name="name()" type="text" />                                      
                </label>                                                                                                                          
                <br />                                                                                                                            
            </xsl:for-each>                                                                                                                       
        </form>                                                                                                                                   
    </xsl:template>                                                                                                                               
</xsl:stylesheet>        

如何使用 Fetch API 来获取 DOM 中已经转换的内容? 这个例子

fetch('ref.xml', )                                                                                                                              
    .then(response => response.text())                                                                                                            
    .then(str =>                                                                                                                                 
        (new window.DOMParser()).parseFromString(str, "text/xml")  
        const app = document.getElementById("content"); 
        app.innerHTML = str;                                                                                                                      
    )      

        

返回未转换的 XML。

PS:我想使用这种方法,因为 jQuery 显然不那么流行了,HTML5 导入功能将来会被删除(它们在我的浏览器上不起作用),最后&lt;object&gt; &lt;embed&gt; &lt;iframe&gt; 标签确实允许我继承 css 并访问内部标签。

【问题讨论】:

“获取已经转换的内容”?哪个工具应该已经转换了内容?您可以将 XML 和 XSLT 提供给 XSLTProcessor 并使用 transformToFragmenttransformToDocument 方法运行转换。您的 fetch 调用执行的 HTTP 请求不会触发 XSLT 处理。 【参考方案1】:

您不仅限于 XSLT 1,还可以在浏览器中使用基于 Saxon-JS 2 的 XSLT 3:

const xml = `<?xml version="1.0" encoding="utf-8"?>                                                                     
<?xml-stylesheet href="trans.xsl" type="text/xsl"?>                                                                          
<profile>                                                                            
  <name>Leonard</name>                                                                            
  <age>99</age>                                                                             
</profile>`;

const xslt = `<?xml version="1.0" encoding="utf-8"?>                                                                          
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="html"/>                                                                                                            
    <xsl:template match="profile"> 
        <form>            
            <xsl:for-each select="child::*">                                                                     
                <label>                                                                                     
                    <xsl:value-of select="name()"/>:                                                                
                    <input name="name()" type="text" />                                      
                </label>                                                                                                                          
                <br />                                                                                                                            
            </xsl:for-each>                                                                                                                       
        </form>                                                                                                                                   
    </xsl:template>                                                                                                                               
</xsl:stylesheet>`;

const transformationResult = SaxonJS.XPath.evaluate(`transform(
    map 
      'source-node' : parse-xml($xml),
      'stylesheet-text' : $xslt,
      'delivery-format': 'raw'
    
  )?output`,
  [],
   params : 
     xml : xml,
     xslt : xslt
  
);

const app = document.getElementById("content"); 
app.textContent = '';
app.appendChild(transformationResult);   
<script src="https://martin-honnen.github.io/xslt3fiddle/js/SaxonJS2.js"></script>

<div id="content"></div>

如果不将 XSLT 预编译为 SEF/JSON,这将与 XSLT 的动态编译同步工作,因此如果您知道 XSLT 将始终相同,它有助于通过 Node.js xslt3 工具运行它(或Saxon EE) 与 -export:trans.xsl.sef.json -nogo -xsl:trans.xsl,然后您甚至可以使用 SaxonJS.transform (https://www.saxonica.com/saxon-js/documentation/index.html#!api/transform) 异步运行 XSLT 转换。

【讨论】:

以上是关于使用 Fetch API 包含使用 XSLT 转换的 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

当属性名称包含特殊字符时,使用 xslt 转换 xml 结果后,输出未以 HTML 格式显示

使用 XSLT 过滤不包含节点的 XYZ

使用 Xslt 将 XML 转换为 XML

C# 中的 XSLT 转换 - 如何获取包含文档的有效 URL?

使用 XSLT 进行属性转换

我的多页迭代 PDF 转换器应该使用啥 XSLT:FO 布局?