当前位置: 移动技术网 > IT编程>开发语言>JavaScript > JaveScript 中使用 XSLT转换XML文档

JaveScript 中使用 XSLT转换XML文档

2018年12月14日  | 移动技术网IT编程  | 我要评论
我们经常将数据存储在XML 中,在展示的时候需要转换为其它的形式,这里介绍使用XSLT 对XML数据进行转换。 要学习XSLT对XML的转换,需要先了解三个文件。 第一个是存储数据的XML文件:employees.xml 第二个是存储XSLT的文件:employees.xslt 第三个是我们进行转换 ...

我们经常将数据存储在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可以节省内存。

 

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网