xslt转换xml文档&&xslt call java方法

经历了上一篇blog,,,发现很多东西会用容易,,,,能简单明了的说明其用法,,,还有点小难,,,,与不擅总结有关吧,,,好了,今天提笔在园里的第二篇blog,,来讲讲xslt转换xml文档以及xslt call java方法的一些使用方法,,写了个开头就不想往下写了有木有,,,唉。

1. 神马是xslt?

XSLT是扩展样式表转换语言(Extensible Stylesheet Language Transformations)的简称,这是一种对XML文档进行转化的语言。见下图。

 

XML Input: xml文档或者关系型数据库中的表

XSLT Code:xslt code用于转换xml文档(blog要介绍的内容哈)

XSLT Processor:xslt处理器,用于将xslt code连接到xml文档完成转换过程

Result Document:经过xslt转换后得到的文档

 

 

 

 

XSLT是XSL规范的一部分。XSL在转换XML文档时分为明显的两个过程,第一转换文档结构;其次将文档格式化输出。这两步可以分离开来并单独处理,因此XSL在发展过程中逐渐分裂为XSLT(结构转换)XSL-FO(formatting objects)(格式化输出)两种分支语言,其中XSL-FO的作用就类似CSSHTML中的作用。而我们这里重点讨论的是第一步的转换过程,也就是XSLT

2. 直接上sample

2.1 xslt将xml文档转换成另一种xml格式

Input XML  

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <t-systems:Persons
 3 xsi:schemaLocation="http://www.t-systems/2013/XMLExample" 
 4 xmlns:t-systems="http://www.t-systems.com/2013/XMLExample"
 5 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
 6 <Person>
 7  <FirstName>David</FirstName>
 8  <LastName>Beckham</LastName>
 9  <BirthDay>811010</BirthDay>
10  <Age>32</Age>
11 </Person>
12 <Person>
13  <FirstName>John</FirstName>
14  <LastName>Beckham</LastName>
15  <BirthDay>810910</BirthDay>
16  <Age>33</Age>
17 </Person>
18 </t-systems:Persons>
View Code

                                                          

Output XML

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <SOAP-ENV:Envelop xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelop"
 3 xmlns:t-systems="http://www.t-systems.com/2013/XMLExample">
 4 <SOAP-ENV:Body>
 5 <t-systems:Persons>
 6 <Person>
 7  <Name>David Beckham</Name>
 8  <BirthDay>1981-10-10</BirthDay>
 9  <Age>32</Age>
10 </Person>
11 <Person>
12  <Name>John Beckham</Name>
13  <BirthDay>1981-09-10</BirthDay>
14  <Age>33</Age>
15 </Person>
16 </t-systems:Persons>
17 </SOAP-ENV:Body>
18 </SOAP-ENV:Envelop>
View Code

 

XSLT Code

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <xsl:stylesheet version="1.0"
 3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 4 xmlns:t-systems="http://www.t-systems.com/2013/XMLExample"
 5 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 6 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 7 exclude-result-prefixes="xs">
 8   <xsl:output method="xml" encoding="UTF-8" indent="no" />
 9   <!-- Entry mapping -->
10   <xsl:template match="/">
11     <SOAP-ENV:Envelope>
12       <SOAP-ENV:Body>
13         <xsl:for-each select="/t-systems:Persons">
14           <t-systems:Persons>
15             <xsl:for-each select="Person">
16               <Person>
17                 <Name>
18                   <xsl:call-template name="ConvertName">
19                     <xsl:with-param name="firstname"
20                     select="FristName" />
21                     <xsl:with-param name="lastname"
22                     select="LastName" />
23                   </xsl:call-template>
24                 </Name>
25                 <BirthDay>
26                   <xsl:call-template name="convert-string-date">
27                     <xsl:with-param name="input"
28                     select="BirthDay" />
29                   </xsl:call-template>
30                 </BirthDay>
31                 <Age>
32                   <xsl:value-of select="Age" />
33                 </Age>
34               </Person>
35             </xsl:for-each>
36           </t-systems:Persons>
37         </xsl:for-each>
38       </SOAP-ENV:Body>
39     </SOAP-ENV:Envelope>
40   </xsl:template>
41   <!-- Concat FirstName and Last Name -->
42   <xsl:template name="ConvertName">
43     <xsl:param name="firstname" />
44     <xsl:param name="lastname" />
45     <xsl:value-of select="concat($firstname,' ',$lastname)" />
46   </xsl:template>
47   <!-- Convert String to Date -->
48   <!-- Convert Date format from String into Date -->
49   <xsl:template name="convert-string-date">
50     <xsl:param name="input" />
51     <xsl:variable name="year"
52     select="concat('19',substring($input,5,2))" />
53     <xsl:variable name="month" select="substring($input,3,2)" />
54     <xsl:variable name="day" select="substring($input,1,2)" />
55     <xsl:value-of select="concat($year,'-',$month,'-',$day)" />
56   </xsl:template>
57 </xsl:stylesheet>
View Code

XSLT Processer

万事俱备,,只差一把东风了:xslt processer。推荐一款必备软件哈,,,Altova XMLSpy,,,专注XML文档process的一个利器。使用方法是,先打开xml input文档,点击XSL/XQuery这个菜单—>XSL转换,,,选取XSLT Code文件就OK了哈。。。不过,这个工具对于call java方法的xslt code文件就不好使了,,对于call java方法的xslt code,java有自己的xml格式转换API—jdk1.5自带的包javax.xml.transform,,会在下面介绍。

xslt中有一个很重要的概念就是:xsl:template.有两种template:named template和template rule. xsl:template元素带name属性的是named template;xsl:template元素带match属性的是template rule.用call-template去使用named template;用apply-template去使用template rule。示例中即有named template也有template rule.

来详细看看sample code中named template的使用方法:

先定义template:

1   <xsl:template name="ConvertName">
2     <xsl:param name="firstname" />
3     <xsl:param name="lastname" />
4     <xsl:value-of select="concat($firstname,' ',$lastname)" />
5   </xsl:template>


再使用template:

<xsl:call-template name="ConvertName">
<xsl:with-param name="firstname"  select="FristName" />
<xsl:with-param name="lastname"   select="LastName" />
</xsl:call-template>

PS:发现了一个笔误,应该为select="FirstName",而不是select="FristName",这个错误在xslt code中也有,后来发现改起来还蛮麻烦,就没有改。

有木有觉得很像方法的调用啊,,,,,xsl:with-param中定义形参;xsl:param中传入实参,,,,然后根据name来调用啊啊啊啊,,,,

xslt code文件的header中还要定义好namespace:命名空间即要定义好xslt本身的命名空间,还要定义input xml和output xml文件中的命名空间,作用是为了使用xpath找到文件中的元素。

2.2 xslt将xml文档转换成html格式

先看下output:                                           

XSLT Code:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <xsl:stylesheet version="1.0"
 3 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 4 xmlns:t-systems="http://www.t-systems.com/2013/XMLExample"
 5 xmlns:xs="http://www.w3.org/2001/XMLSchema"
 6 xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
 7 exclude-result-prefixes="xs">
 8   <xsl:output method="html" encoding="UTF-8" indent="no" />
 9   <!-- Entry mapping -->
10   <xsl:template match="/">
11     <body>
12       <xsl:for-each select="/t-systems:Persons">
13         <center>
14           <table border="1">
15             <tr>
16               <th>Name</th>
17               <th>BirthDay</th>
18               <th>Age</th>
19             </tr>
20             <xsl:for-each select="Person">
21               <tr>
22                 <td>
23                   <xsl:call-template name="ConvertName">
24                     <xsl:with-param name="firstname"
25                     select="FirstName" />
26                     <xsl:with-param name="lastname"
27                     select="LastName" />
28                   </xsl:call-template>
29                 </td>
30                 <td>
31                   <xsl:call-template name="convert-string-date">
32                     <xsl:with-param name="input"
33                     select="BirthDay" />
34                   </xsl:call-template>
35                 </td>
36                 <td>
37                   <xsl:value-of select="Age" />
38                 </td>
39               </tr>
40             </xsl:for-each>
41           </table>
42         </center>
43       </xsl:for-each>
44     </body>
45   </xsl:template>
46   <!-- Concat FirstName and Last Name -->
47   <xsl:template name="ConvertName">
48     <xsl:param name="firstname" />
49     <xsl:param name="lastname" />
50     <xsl:value-of select="concat($firstname,' ',$lastname)" />
51   </xsl:template>
52   <!-- Convert String to Date -->
53   <!-- Convert Date format from String into Date -->
54   <xsl:template name="convert-string-date">
55     <xsl:param name="input" />
56     <xsl:variable name="year"
57     select="concat('19',substring($input,5,2))" />
58     <xsl:variable name="month" select="substring($input,3,2)" />
59     <xsl:variable name="day" select="substring($input,1,2)" />
60     <xsl:value-of select="concat($year,'-',$month,'-',$day)" />
61   </xsl:template>
62 </xsl:stylesheet>
View Code

好伐,,,,下面开讲xslt call java方法喽。
3. XSLT call java方法

对于xslt中转换name的显示方式的例子,,,,我们不用template做,,,,改成用java方法来做。如下:

1 public class TestCallJavaMethod {
2     
3 public static String convertName(String firstName, String lastName){
4         
5 return firstName+" "+lastName;
6 }
7 }

详细步骤来了:

3.1 将java class加入xslt code的namespace中

xmlns:javacode="demo.TestCallJavaMethod”  exclude-result-prefixes="xs javacode"

demo是java class存放的包名;exclude-result-prefixes用来表示在output xml中不显示xs和javacode这两个命名空间前缀。

3.2 定义xslt变量去存储参数的值

先从input xml获取firstName和lastName的值

<xsl:variable name="firstName" select="FirstName" />

<xsl:variable name="lastName" select="LastName" />

3.3 XSLT转换xml文档—call java方法

<xsl:variable name="convertName" select="javacode:convertName($firstName,$lastName)" />

<xsl:value-of select="$convertName" />

用call java方法实现2.1中转换xml文档

XSLT Code

 

 1 <?xml version="1.0" encoding="UTF-8"?>
 2  <xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 3   xmlns:t-systems="http://www.t-systems.com/2013/XMLExample" 
 4   xmlns:javacode="demo.TestCallJavaMethod”
 5   xmlns:xs="http://www.w3.org/2001/XMLSchema" 
 6   xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" exclude-result-prefixes="xs javacode">
 7  <xsl:output method="xml" encoding="UTF-8" indent="no"/>
 8    <!-- Entry mapping -->
 9    <xsl:template match="/">
10      <SOAP-ENV:Envelope>
11        <SOAP-ENV:Body>
12          <xsl:for-each select="/t-systems:Persons">
13            <t-systems:Persons>
14              <xsl:for-each select="Person">
15                <Person>
16                  <Name>
17                        <xsl:variable name="firstName" select="FirstName" />
18                       <xsl:variable name="lastName" select="LastName" />
19                       <xsl:variable name="convertName" select="javacode:convertName($firstName,$lastName)" />
20                       <xsl:value-of select="$convertName" />
21                  </Name>
22                  <BirthDay>
23                    <xsl:call-template name="convert-string-date">
24                      <xsl:with-param name="input" select="BirthDay" />
25                    </xsl:call-template>
26                  </BirthDay>
27                  <Age><xsl:value-of select="Age" /></Age>                
28                </Person>
29              </xsl:for-each>
30            </t-systems:Persons>
31          </xsl:for-each>
32        </SOAP-ENV:Body>
33      </SOAP-ENV:Envelope>
34    </xsl:template>
35    <!-- Convert String to Date -->
36    <!-- Convert Date format from String into Date -->
37    <xsl:template name="convert-string-date">
38      <xsl:param name="input" />
39      <xsl:variable name="year"
40      select="concat('19',substring($input,5,2))" />
41      <xsl:variable name="month" select="substring($input,3,2)" />
42      <xsl:variable name="day" select="substring($input,1,2)" /> 
43      <xsl:value-of select="concat($year,'-',$month,'-',$day)" />
44    </xsl:template>
45  </xsl:stylesheet>
View Code

用于transform的JAVA Code

 

 1 package demo;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.xml.transform.OutputKeys;
 6 import javax.xml.transform.Result;
 7 import javax.xml.transform.Source;
 8 import javax.xml.transform.Transformer;
 9 import javax.xml.transform.TransformerException;
10 import javax.xml.transform.TransformerFactory;
11 import javax.xml.transform.stream.StreamResult;
12 import javax.xml.transform.stream.StreamSource;
13 
14 public class TransformerDemo {
15     
16     public static void main(String[] args) throws TransformerException, IOException {
17           Source source = new StreamSource("src/com/demo/input2.xml");
18           Source xsl = new StreamSource("src/com/demo/sample3.xsl");
19           Result result = new StreamResult(System.out);
20 
21           TransformerFactory factory = TransformerFactory.newInstance();
22           Transformer transformer = factory.newTransformer(xsl);
23           transformer.setOutputProperty(OutputKeys.INDENT, "yes");
24           transformer.transform(source, result);
25     }
26 
27 }
View Code

 

 

Tips:XSLT Call Java方法只能call java 中的static方法哈,,,切记啊,,,,xslt若想call java中的字段的话(如firstName),应先把字段用get()方法转换成static(getFirstName()),,再用xslt去call getFirstName()这个方法就好了。。。

另外,如果直接将xml,或者xsl文件的内容copy下来用于新建文件的时候,可能会出现“org.xml.sax.SAXParseException: Content is not allowed in prolog”的异常,这是因为有些编辑器会给文本加上BOM头。解决方案就是去除BOM头就可以了。怎么去?百度一下,你就知道。怎么验证是否去除成功?使用NotePad++,或者UltraEdit,或者EditPlus以十六进制的方式打开就可以看到了哈。

OMG,终于说完,,,,第二篇blog了,,,自豪瓦。。。。。。 

posted @ 2013-05-22 11:55  alvwood  阅读(1240)  评论(2编辑  收藏  举报