• JaveScript 中使用 XSLT转换XML文档


    我们经常将数据存储在XML 中,在展示的时候需要转换为其它的形式,这里介绍使用XSLT 对XML数据进行转换。

    要学习XSLT对XML的转换,需要先了解三个文件。

    第一个是存储数据的XML文件:employees.xml

    <?xml version="1.0"?>
    <employees>
        <employee title="Software Engineer">
            <name>Nicholas C. Zakas</name>
        </employee>
        <employee title="Salesperson">
            <name>Jim Smith</name>
        </employee>
    </employees>

    第二个是存储XSLT的文件:employees.xslt

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:output method="html" />
        
        <xsl:template match="/">
           <ul>
               <xsl:apply-templates select="*" />
           </ul>
        </xsl:template>
    
        <xsl:template match="employee">
            <li><xsl:value-of select="name" />, <em><xsl:value-of select="@title" /></em></li>
        </xsl:template>
    
    </xsl:stylesheet>

    第三个是我们进行转换的代码example.htm:

     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <title>XSLTProcessor Example</title>   
     5 
     6     <script type="text/javascript">
     7         window.onload = function () {
     8         
     9             //use XHR to load
    10             var xmlhttp = new XMLHttpRequest();
    11             xmlhttp.open("get", "employees.xml", false);
    12             xmlhttp.send(null);
    13             var xmldom = xmlhttp.responseXML;
    14             
    15             xmlhttp = new XMLHttpRequest();
    16             xmlhttp.open("get", "employees.xslt", false);
    17             xmlhttp.send(null);
    18             var xsltdom = xmlhttp.responseXML;  
    19 
    20             var processor = new XSLTProcessor();
    21             processor.importStylesheet(xsltdom);
    22 
    23             var result = processor.transformToDocument(xmldom);
    24             var div = document.getElementById("divResult");
    25             
    26             var xml = (new XMLSerializer()).serializeToString(result);
    27             alert(xml);
    28             div.innerHTML = xml;
    29 
    30         }
    31     </script>           
    32 </head>
    33 <body>
    34     <p>This example loads employees.xml and transforms it using employees.xslt. 
    35     The resulting code is then displayed.</p>
    36     <div id="divResult"></div>
    37 </body>
    38 </html>

    在这里我们通过 XSLTProcessor 类型使用XSLT转换XML文档,第一步加载两个DOM文档,一个基于XML,另一个基于XSLT,下面的代码在Edge 中可以顺利执行,在Chrome中,因为禁止从本地装载文件随意会会失败,如果从网络服务器上读取数据则没有问题。

    //use XHR to load
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("get", "employees.xml", false);
    xmlhttp.send(null);
    var xmldom = xmlhttp.responseXML;
                
    xmlhttp = new XMLHttpRequest();
    xmlhttp.open("get", "employees.xslt", false);
    xmlhttp.send(null);
    var xsltdom = xmlhttp.responseXML;  

    然后创建一个新XSLTProcessor对象,并使用importStylesheet()方法为其指定一个XSLT

    var processor = new XSLTProcessor();
    processor.importStylesheet(xsltdom);

     最后一步是执行转换,这一步有两种不同的方式,如果想返回一个完整的DOM文档,可以调用transformToDocument().而通过调用transforToFragment()则可以得到一个文档片段对象。一般来说。使用transformToFragment()的唯一理由,就是你想把返回的结果添加到另一个DOM文档中。

    在使用transforToDocument()时,只要传入XML DOM,就可以将结果作为一个完全不同的DOM文档来使用。来看例子

    var result = processor.transformToDocument(xmldom);

    我们将result 结果进行序列化

    var xml = (new XMLSerializer()).serializeToString(result);

    来看转换后的结果

    <ul>
    <li>Nicholas C. Zakas, <em>Software Engineer</em></li>
    <li>Jim Smith, <em>Salesperson</em></li>
    </ul>

    下面我们来看一下XSLT中的定义:

    下面的这段代码会让我们将所有的内容都放到<ul></ul>之中,之所以会这样是因为我们的选择符指定了全部 select="*"

    <xsl:template match="/">
           <ul>
               <xsl:apply-templates select="*" />
           </ul>
    </xsl:template>

    下面这段代码的含义是对 employee 元素进行转换 match="employee"

    将name 元素放到<li></li>中  select="name"

    将title 属性提取出来放到<em></em>中  select="@title"

     <xsl:template match="employee">
            <li><xsl:value-of select="name" />, <em><xsl:value-of select="@title" /></em></li>
    </xsl:template>

    而transformToFragment()方法接收两个参数:要转换的XML DOM 和应该拥有结果片段的文档。换句话说,如果你想将返回的片段插入到页面中,只要将document作为第二个参数即可。

    我们只需要将example.htm中 23 - 28 行代码替换成下面代码就可以了。

    var fragment = processor.transformToFragment(xmldom, document);
    var div = document.getElementById("divResult");
                
    div.appendChild(fragment);

    这里,处理器创建了一个有document对象拥有的片段。这样,就可以将返回的片段添加到页面中已有的<div>元素中了。

    在XSLT样式表的输出格式为"xml","html"的情况下,创建文档或文档片段会非常有用。

    1.使用参数

    XSLTProcessor 也支持使用 setParameter()来设置XSLT的参数,这个方法接收三个参数:命名空间URI,参数的内部名称和要设置的值。通常,命名空间URI都是null,而内部名称就是参数的名称。另外必须在调用transformToDocument()或transformToFragment()之前调用这个方法。来看例子

    我们先看XSLT文件 employees2.xslt:

    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:output method="html" />
    
        <xsl:param name="message" />
            
        <xsl:template match="/">
           <ul>
               <xsl:apply-templates select="*" />
           </ul>
           <p>Message: <xsl:value-of select="$message" /></p>
        </xsl:template>
    
        <xsl:template match="employee">
            <li><xsl:value-of select="name" />, <em><xsl:value-of select="@title" /></em></li>
        </xsl:template>
    
    </xsl:stylesheet>

    针对 example.htm的修改

    第16行替换为

    xmlhttp.open("get", "employees2.xslt", false);

    第23 - 28替换为下面代码

    processor.setParameter(null, "message", "Hello World!");
    
    var fragment = processor.transformToFragment(xmldom, document);
    var div = document.getElementById("divResult");
                
    div.appendChild(fragment);            

    我们看运行后的结果:通过转换将模板中的 $message变量替换成了我们传入的参数"Hello World!"

    <div id="divResult"><ul>
    <li>Nicholas C. Zakas, <em>Software Engineer</em></li>
    <li>Jim Smith, <em>Salesperson</em></li>
    </ul>
    <p>Message: Hello World!</p>
    </div>

    还有两个与参数有关的方法,getParamenter()和removeParamenter(),分别用于取得和一处当前参数的值。这两个方法都要接受命名空间参数和参数内部i名称。例如

    var processor = new XSLTProcessor();
    processor.importStylesheet(xsltdom);
    processor.setParameter(null, "message", "Hello World!");
    
    alert(processor.getParaeter(null,"message")); //输出 “Hello World!"
    processor.removeParameter(null,"message");
    var fragment = processor.transformToFragment(xmldom, document);

    这两个方法并不常用。

    2.重置处理器

    每个XSLTProcessor 的实例都可以重用,以便使用不同的XSLT样式表执行不同的转换。重置处理器时要调用reset()方法,这个方法会从处理器中移除所有的参数和样式表。然后,你就可以再次调用importStylesheet(),以加载不同的XSLT样式表,如下面的例子

    var processor = new XSLTProcessor();
    processor.importStylesheet(xsltdom);

    //执行转换

    processor.reset();
    processor.importStylesheet(xsltdom2);

    //在执行转换

    在需要基于多个样式表进行转换时,重用一个XSLTProcessor可以节省内存。

  • 相关阅读:
    Vue-ui常用组件库整理
    给博客添加fork me on github图标
    element-ui 带单选框的表格
    css grid 网格布局
    TensorFlow学习笔记(6):TensorBoard之Embeddings
    ES6 异步编程之一:Generator
    浅析 Node.js 的 vm 模块以及运行不信任代码
    使用 D8 分析 javascript 如何被 V8 引擎优化的
    深入新版BS4源码 探索flex和工程化sass奥秘
    PHP-7.1 源代码学习:字节码生成 之 "$a = 1"
  • 原文地址:https://www.cnblogs.com/xixiuling/p/10116108.html
Copyright © 2020-2023  润新知