XSL基本用法

xsl本身就是一个构型良好的xml,它能够把一个xml文档转换成另外一个xml文档,或者转换成文本文件、html文件等等。这里就是利用xsl来动态的生成我们想要的java文件(从某种角度看,java代码其实也就是一个文本文件),希望能够通过这篇文章,看到xml以及相关的技术所具有的强大能力!

这里首先给一个xml例子,我们将通过一个xsl从该xml文件中抽取有用的信息来生成java代码(实际上是一个javabean):
[code]
<?xml version="1.0" encoding="ISO-8859-1" ?>
 
<bean>
    <name>Product</name>
 
    <comments>This bean represents a product that thecompany
offers to its customers</comments>
 
    <property>
        <name>code</name>
 
        <type>int</type>
 
        <comments>the productinventory code</comments>
 
    </property>
    <property>
        <name>name</name>
 
        <type>String</type>
 
        <comments>the productname</comments>
 
    </property>
    <property>
        <name>testedOnAnimals</name>
 
        <type>boolean</type>
 
        <comments>the flag thatindicates if the product was
tested on animals</comments>
 
    </property>
    <property>
        <name>availableSince</name>
 
        <type>java.util.Date</type>
 
        <comments>the date whenthe company started offering this
product to its customers</comments>
 
    </property>
</bean>
 
[/code]

下面我就直接给出转换的xsl,如果大家对xsl不是很了解的话,可以先看一些资料,了解之后就会明白了。我在里面稍微做了些注释:
[code]
<?xml version="1.0"?>
<xsl:stylesheet
 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 
    version="1.0"   
    xmlns:java="http://xml.apache.org/xslt/java"
    exclude-result-prefixes="java">

<!--
这里就是指定通过这个xsl所转换的结果的类型,是text格式-->
<xsl:output method = "text"/>

<!--xslt
使用模版来处理xml中的节点-->
<xsl:template match="bean">

/**
* <xsl:value-of select="comments"/>//
这里是获取xml文档中的节点值
* This class has been generated by the XSLT processor from the
metadata
 
*/
public class <xsl:value-of select="name"/> {

    /**
     * Creates a new instance of the <xsl:value-of
select="name"/> bean
     */
    public <xsl:value-of select="name"/>(){}
         
    <xsl:apply-templates select="property"/>
}
</xsl:template>

<xsl:template match="property">
    private <xsl:value-ofselect="type"/>
    <xsl:text> </xsl:text>//
输出文本,这里是输出一个空格
    <xsl:value-of select="name"/>;
    <xsl:variable name="name"select="name"/>//
定义xsl中要使用的变量
    <xsl:variable name="cname"select="java:Capitalizer.capitalize($name)"/>//
这里使用了xsltextensions,它可以允许在xslt中直接引用java中方法,非常方便。
    /**
     * Sets <xsl:value-ofselect="comments"/>
     * @param <xsl:value-ofselect="name"/> is <xsl:value-of
select="comments"/>
     */
    public void set<xsl:value-ofselect="$cname"/>(<xsl:value-
of select="type"/> <xsl:text></xsl:text><xsl:value-
of select="name"/>) {
      this.<xsl:value-ofselect="name"/> = <xsl:value-of
select="name"/>;          
    }

    /**
     * Returns <xsl:value-ofselect="comments"/>
     * @return <xsl:value-ofselect="comments"/>
     */
    public <xsl:value-ofselect="type"/><xsl:text></xsl:text>
    <xsl:apply-templatesselect="type"/><xsl:value-of
    select="$cname"/>() {
      return <xsl:value-of select="name"/>;
    }
</xsl:template>

<xsl:template match="type">
    <xsl:variable name="type"select="."/>
    <xsl:choose>
    <xsl:whentest="$type='boolean'">is</xsl:when>
    <xsl:otherwise>get</xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>
[/code]

好了,完成以上工作之后,只要在cmd中,输入如下的命令行,就可以获得我们想要的结果了:
java org.apache.xalan.xslt.Process -in xmlSource  -xsl stylesheet-out outputfile
 

这里列出结果:
[code]
/**
* This bean represents a product that the company offers to its
customers
* This class has been generated by the XSLT processor from the
metadata
*/
public class Product {

    /**
     * Creates a new instance of the Product bean
     */
    public Product() {}
         
         
    private int code;
         
    /**
     * Sets the product inventory code
     * @param code is the product inventory code
     */
    public void setCode(int code) {
        this.code =code;          
    }

    /**
     * Returns the product inventory code
     * @return the product inventory code
     */
    public int getCode() {
        return code;
    }

    private String name;
         
    /**
     * Sets the product name
     * @param name is the product name
     */
    public void setName(String name) {
        this.name =name;          
    }

    /**
     * Returns the product name
     * @return the product name
     */
    public String getName() {
        return name;
    }

    private boolean testedOnAnimals;
         
    /**
    * Sets the flag that indicates if the product wastested on animals
    * @param testedOnAnimals is the flag that indicates ifthe product
was tested on animals
    */
    public void setTestedOnAnimals(boolean testedOnAnimals){
        this.testedOnAnimals =testedOnAnimals;          
    }

    /**
     * Returns the flag that indicates if the productwas tested on
animals
     * @return the flag that indicates if the productwas tested on
animals
     */
    public boolean isTestedOnAnimals() {
        return testedOnAnimals;
    }

    private java.util.Date availableSince;
         
    /**
     * Sets the date when the company started offeringthis product to
its customers
     * @param availableSince is the date when thecompany started
offering this product to its customers
     */
    public void setAvailableSince(java.util.DateavailableSince) {
        this.availableSince =availableSince;          
    }

    /**
     * Returns the date when the company startedoffering this product
to its customers
     * @return the date when the company startedoffering this product
to its customers
     */
    public java.util.Date getAvailableSince() {
        return availableSince;
    }

}
[/code]

总结:
1.
在熟悉了xsl的基本使用之后,理解以上的内容并不是困难;
2.
这样做是比较适合预先知道了某些逻辑功能,但由于某种原因,需要动态生成,或者是为了节省不必要的重复工作,可以通过它自动生成代码;
3.
修改这个xsl比较方便。

java xsl转换方法

XSL是指可扩展样式表语言 (EXtensible Stylesheet Language),是一种用于以可读格式呈现 XML 数据的语言。XSLTEXtensible Stylesheet Language Transformation)可以将XML文档转换为其他格式,比如方便阅读的HTML或者纯文本。

要实现XSL转换,首先要提供XSLT样式表,它描述了XML文档像某种其他格式换换的规则,XSLT处理器将读入XML文档和样式表,并产生所要的输出。

看一段XML文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

<staff>

   <employee>

      <name>Carl Cracker</name>

      <salary>75000</salary>

      <hiredate year="1987" month="12" day="15"/>

   </employee>

   <employee>

      <name>Harry Hacker</name>

      <salary>50000</salary>

      <hiredate year="1989" month="10" day="1"/>

   </employee>

   <employee>

      <name>Tony Tester</name>

      <salary>40000</salary>

      <hiredate year="1990" month="3" day="15"/>

   </employee>

</staff>

现在需要输出一张HTML表格:

1

2

3

4

5

6

7

8

9

10

11

<table border="1">

<tr>

<td>Carl Cracker</td><td>$75000.0</td><td>1987-12-15</td>

</tr>

<tr>

<td>Harry Hacker</td><td>$50000.0</td><td>1989-10-1</td>

</tr>

<tr>

<td>Tony Tester</td><td>$40000.0</td><td>1990-3-15</td>

</tr>

</table>

这里我们重点不在如何书写XSLT上,我们只关心Java如何使用XSL进行转换。更多关于XSL的见http://www.w3.org/TR/xslt.

XSLT样式表的格式如下:

1

2

3

4

5

6

7

8

9

?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet

   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

   version="1.0">

   <xsl:output method="html"/>

   template1

   template2

   . . .

</xsl:stylesheet>

在上面的例子中,需要把XML转换为HTML,所以这里使用xsl:output=”html”,另外还有两种有效的设置xmltext

看一段简单的XSL样式表的片段:

1

2

3

<xsl:template  match="/staff/employee">

   <tr><xsl:apply-templates/></tr>

</xsl:template>

match的属性值是一个XPath表达式,该片段的作用为,每遇到一个XPath/staff/employee的节点时:

1.    产生字符串<tr>

2.    对于要处理的子元素继续应用该模板(template

3.    当处理所有子元素后,产生字符串</tr>

这段代码就用于为每个雇员记录生成HTML表格的行标记。

接着看如何处理雇员记录信息:

1

2

3

<xsl:template  match="/staff/employee/name">

   <td><xsl:apply-templates/></td>

</xsl:template>

这里将产生HTML标签<td>…</td>,并且请求处理器地归访问name元素的子节点。在这里它只有一个子节点——文本节点,当处理器访问该节点的时候,产生文本内容。

处理属性就相对复杂一点:

1

2

3

4

<xsl:template  match="/staff/employee/hiredate">

   <td><xsl:value-of select="@year"/>-<xsl:value-of

   select="@month"/>-<xsl:value-of select="@day"/></td>

</xsl:template>

当处理hiredate时候,将产生:

1.    字符串<td>

2.    year属性值

3.    连接符-

4.    month属性值

5.    连接符-

6.    day属性值

7.    连接符-

8.    字符串</td>

xsl:value-of语句用户计算节点集的字符串值,select属性值为XPath,提供计算的节点集。

完整的看看整个将XML转换为HTML表格的XSL样式表:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

<?xml version="1.0" encoding="ISO-8859-1"?>

 

 <xsl:stylesheet

    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

    version="1.0">

 

    <xsl:output method="html"/>

 

    <xsl:template match="/staff">

      <table border="1"><xsl:apply-templates/></table>

   </xsl:template>

 

   <xsl:template match="/staff/employee">

      <tr><xsl:apply-templates/></tr>

   </xsl:template>

 

   <xsl:template match="/staff/employee/name">

      <td><xsl:apply-templates/></td>

   </xsl:template>

 

   <xsl:template match="/staff/employee/salary">

      <td>$<xsl:apply-templates/></td>

   </xsl:template>

 

   <xsl:template match="/staff/employee/hiredate">

      <td><xsl:value-of select="@year"/>-<xsl:value-of

      select="@month"/>-<xsl:value-of select="@day"/></td>

   </xsl:template>

 

</xsl:stylesheet>

再看看一个将XML转换为TXT文本的样式表:

<?xmlversion="1.0"?>

 

  <xsl:stylesheet

     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"

     version="1.0">

 

     <xsl:outputmethod="text"/>

 

     <xsl:templatematch="/staff/employee">

 employee.<xsl:value-ofselect="position()"/>.name=<xsl:value-ofselect="name/text()"/>

 employee.<xsl:value-ofselect="position()"/>.salary=<xsl:value-ofselect="salary/text()"/>

 employee.<xsl:value-ofselect="position()"/>.hiredate=<xsl:value-ofselect="hiredate

/@year"/>-<xsl:value-ofselect="hiredate/@month"/>-<xsl:value-ofselect="hiredate/@day"/>

    </xsl:template>

 

 </xsl:stylesheet>

TXT的输出结果为:

employee.1.name=Carl Cracker
employee.1.salary=75000.0
employee.1.hiredate=1987-12-15
employee.2.name=Harry Hacker
employee.2.salary=50000.0
employee.2.hiredate=1989-10-1
employee.3.name=Tony Tester
employee.3.salary=40000.0
employee.3.hiredate=1990-3-15

看看如何使用Java进行转换:

File styleSheet = newFile(filename);

StreamSource styleSource = newStreamSource(styleSheet);

Transformer t =TransformerFactory.newInstance().newTransformer(styleSource);

t.transform(source, result);

 

line 249

transform的第一个参数为Source,它可以是:

DOMSource

SAXSource

StreamSource

比如使用DOM树节点进行转换:

1

t.transform(new DOMSource(doc), result);

第二个参数为Resout,它可以是:

DOMResult

SAXResult

StreamResult

比如把转换结果存储到DOM树中:

1

2

Document doc = builder.newDocument();

t.transform(source, new DOMResult(doc));

存储到文件中:

1

t.transform(source, new StreamResult(file));

看一个完整的示例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.util.StringTokenizer;

 

import javax.xml.transform.Transformer;

import javax.xml.transform.TransformerFactory;

import javax.xml.transform.sax.SAXSource;

import javax.xml.transform.stream.StreamResult;

import javax.xml.transform.stream.StreamSource;

 

import org.xml.sax.ContentHandler;

import org.xml.sax.DTDHandler;

import org.xml.sax.EntityResolver;

import org.xml.sax.ErrorHandler;

import org.xml.sax.InputSource;

import org.xml.sax.SAXException;

import org.xml.sax.XMLReader;

import org.xml.sax.helpers.AttributesImpl;

 

/**

 * This program demonstrates XSL transformations. It applies a transformation to

 * a set of employee records. The records are stored in the file employee.dat

 * and turned into XML format. Specify the stylesheet on the command line, e.g.

 * java TransformTest makeprop.xsl

 */

public class TransformTest {

    public static void main(String[] args) throws Exception {

        String filename;

        if (args.length > 0)

            filename = args[0];

        else

            filename = "makehtml.xsl";

        File styleSheet = new File(filename);

        StreamSource styleSource = new StreamSource(styleSheet);

 

        Transformer t = TransformerFactory.newInstance().newTransformer(

                styleSource);

        t.transform(new SAXSource(new EmployeeReader(), new InputSource(

                new FileInputStream("employee.dat"))), new StreamResult(

                System.out));

    }

}

 

/**

 * This class reads the flat file employee.dat and reports SAX parser events to

 * act as if it was parsing an XML file.

 */

class EmployeeReader implements XMLReader {

    public void parse(InputSource source) throws IOException, SAXException {

        InputStream stream = source.getByteStream();

        BufferedReader in = new BufferedReader(new InputStreamReader(stream));

        String rootElement = "staff";

        AttributesImpl atts = new AttributesImpl();

 

        if (handler == null)

            throw new SAXException("No content handler");

 

        handler.startDocument();

        handler.startElement("", rootElement, rootElement, atts);

        String line;

        while ((line = in.readLine()) != null) {

            handler.startElement("", "employee", "employee", atts);

            StringTokenizer t = new StringTokenizer(line, "|");

 

            handler.startElement("", "name", "name", atts);

            String s = t.nextToken();

            handler.characters(s.toCharArray(), 0, s.length());

            handler.endElement("", "name", "name");

 

            handler.startElement("", "salary", "salary", atts);

            s = t.nextToken();

            handler.characters(s.toCharArray(), 0, s.length());

            handler.endElement("", "salary", "salary");

 

            atts.addAttribute("", "year", "year", "CDATA", t.nextToken());

            atts.addAttribute("", "month", "month", "CDATA", t.nextToken());

            atts.addAttribute("", "day", "day", "CDATA", t.nextToken());

            handler.startElement("", "hiredate", "hiredate", atts);

            handler.endElement("", "hiredate", "hiredate");

            atts.clear();

 

            handler.endElement("", "employee", "employee");

        }

 

        handler.endElement("", rootElement, rootElement);

        handler.endDocument();

    }

 

    public void setContentHandler(ContentHandler newValue) {

        handler = newValue;

    }

 

    public ContentHandler getContentHandler() {

        return handler;

    }

 

    // the following methods are just do-nothing implementations

    public void parse(String systemId) throws IOException, SAXException {

    }

 

    public void setErrorHandler(ErrorHandler handler) {

    }

 

    public ErrorHandler getErrorHandler() {

        return null;

    }

 

    public void setDTDHandler(DTDHandler handler) {

    }

 

    public DTDHandler getDTDHandler() {

        return null;

    }

 

    public void setEntityResolver(EntityResolver resolver) {

    }

 

    public EntityResolver getEntityResolver() {

        return null;

    }

 

    public void setProperty(String name, Object value) {

    }

 

    public Object getProperty(String name) {

        return null;

    }

 

    public void setFeature(String name, boolean value) {

    }

 

    public boolean getFeature(String name) {

        return false;

    }

 

    private ContentHandler handler;

}

 

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值