Java XML编程

1.   Java XML编程概述

在这里,主要是通过给出一些例子,来理清SAXDOMJDOMJXAP四者之间的关系。首先,SAXDOM是最基础的解释器接口。而JDOM是在模型上统一了SAXDOM,使得SAXDOM处理的结果都为一个JDocumentJAXP则是在API上统一了各SAX和各DOM,他的作用有点类似于JDBC,隐藏了底层采用的具体的SAXDOM解释器,而提供统一API编程接口。

 

2.   XML文件

1.xml(用于下文显示)

<?xml version="1.0" encoding="gb2312"?>

<statistic>

<header>

     <column name="Cache大小"/>

     <column name="Cache命中"/>

     <column name="时间(ms)"/>

</header>

<data>

     <x value="10">

          <y value="493"/>

          <y value="1281"/>

     </x>

     <x value="11">

          <y value="560"/>

          <y value="1063"/>

     </x>

</data>

</statistic>

 

3.   SAX 2.0

a)        模型:

 

XMLReader

ContentHandler

DTDHandler

ErrorHandler

 

 

 

 

 

 

 

 

 


b)        模型说明:

SAX的实现模型采用了Builder的设计模式。XMLReader负责XML文件的读取和识别,并且根据文本的识别结果,产生对应的事件通知,随后将这些事件发送到注册在XMLReader上的各种Handler。这样做的好处是系统只需要一个单独的XMLReader负责完成XML文件的解释,而具体这些被解释的内容做何种用途,则由用户所实现的Handler来定义。

c)        代码:

MyContentHandler的实现代码:

package sax;

import org.xml.sax.*;

import org.xml.sax.helpers.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class MyHandler extends DefaultHandler {

    private int indent = 0;

    public void startElement(String uri, String localName, String qName,

            Attributes attrs) {

        emit();

        System.out.print("<" + localName);

        int count = attrs.getLength();

        for (int i = 0; i < count; i++) {

            System.out.print(" " + attrs.getLocalName(i) + "=/""

                    + attrs.getValue(i) + "/"");

        }

        System.out.println(">");

        indent++;

    }

    public void endElement(String uri, String localName, String qName) {

        indent--;

        emit();

        System.out.println("</" + localName + ">");

    }

    public void characters(char[] ch, int start, int length) {

        String text = String.valueOf(ch, start, length);

        if (!("".equals(text.trim())))

            System.out.println();

    }

    private void emit() {

        for (int i = 0; i < indent; i++)

            System.out.print("/t");

    }

}

 

测试代码:

package sax;

 

import java.io.*;

import org.xml.sax.*;

import org.xml.sax.helpers.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Test {

    public static void main(String[] args) {

        try {

            XMLReader reader = XMLReaderFactory.createXMLReader();

            reader.setContentHandler(new MyHandler());           

            reader.parse(new InputSource(new FileReader("1.xml")));

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

 

输出:

<statistic>

     <header>

         <column name="Cache大小">

         </column>

         <column name="Cache命中">

         </column>

         <column name="时间(ms)">

         </column>

     </header>

     <data>

         <x value="10">

              <y value="493">

              </y>

              <y value="1281">

              </y>

         </x>

         <x value="11">

              <y value="560">

              </y>

              <y value="1063">

              </y>

         </x>

     </data>

</statistic>

 

 

注:MyHandler的作用是一个简单的XML文件显示器。她输出XML文件中的所有元素标签,以及元素中的属性和文本。

 

d)        XMLFilter

顾名思义,XMLFilter主要用于对XML文件的内容进行过滤。

                      i.              模型:

 

event

event

event

parse()

parse()

XMLReader

XMLFilter1

XMLFilter2

ContentHandler

 

 

 

 

 

 

 

 


                   ii.              模型说明:

XMLFilter模型的实现主要是采用了责任连的模式。XMLFitler扩展了XMLReader接口,而XMLFilter的实现类XMLFilterImpl实现了ContentHandlerDTDHandler等接口,因此XMLFilterImpl可以作为普通的Handler注册到XMLReader上。另外XMLFilterImpl的构造函数中,她通过接受一个XMLReader实例作为她的父引用,从而可以把多个XMLFilter串成一个责任链,进行多级过滤。

 

                iii.              代码:

MyFilter的实现代码:

package sax;

import org.xml.sax.*;

import org.xml.sax.helpers.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class MyFilter extends XMLFilterImpl {

    public MyFilter(XMLReader reader) {

        super(reader);

    }

    public void startElement(String uri, String localName, String qName,

            Attributes atts) {

        try {

            if ("data".equals(qName)) {

                return;

            } else {

                super.startElement(uri, localName, qName, atts);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    public void endElement(String uri, String localName, String qName) {

        try {

            if ("data".equals(qName)) {

                return;

            } else {

                super.endElement(uri, localName, qName);

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

 

测试代码:

package sax;

import java.io.*;

import org.xml.sax.*;

import org.xml.sax.helpers.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Test {

    public static void main(String[] args) {

        try {

            XMLReader reader = XMLReaderFactory.createXMLReader();

            MyFilter filter = new MyFilter(reader);

            filter.setContentHandler(new MyHandler());

            filter.parse(new InputSource(new FileReader("1.xml")));

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

 

输出:

<statistic>

     <header>

         <column name="Cache大小">

         </column>

         <column name="Cache命中">

         </column>

         <column name="时间(ms)">

         </column>

     </header>

     <x value="10">

         <y value="493">

         </y>

         <y value="1281">

         </y>

     </x>

     <x value="11">

         <y value="560">

         </y>

         <y value="1063">

         </y>

     </x>

</statistic>

 

注:MyFilter的作用就是过滤调名称为data的标签,不在结果中输出。

 

                   iv.              注意事项:

由于XMLFilter本身并不具备解释XML文档的能力,因此在构造Filter Chain时,在最高层的必须是XMLReader实例。

 

e)        Handler介绍:

除了常用的ContentHandlerDTDHandlerHandler之外。还有以下几个属于SAX 2.0的,新的Handler

                      i.              LexicalHandler

用于处理由DTD,注释,CDATA字段触发的事件。

                   ii.              DeclHandler

用于处理DTD中的ELEMENTATTRIBUTE定义所触发的事件。

 

f)        FeatureProperties

通过setProperty()getProperty()可以对XMLReader上的属性进行操作。通过setFeature()getFeature()可以对XMLReader上的特征进行操作。主要是检查ValidateNamespace等方面的属性。FeatureProperties是解释器相关的,因此具体能设置哪些FeatureProperties需要查看解释器的实现文档。

 

 

 

 

 

 

 

 

4.   DOM 1.0

a)        模型:

 

DOMParser

Document

 

 

 

 

 

 

 


b)        模型说明:

DOM的实现模型与SAX的最主要区别是,用户并不是直接在XML文件上操作。而是由DOM解释器先对文件进行解释,然后生成符合该XML文件结构的一棵DOM树,最后用户程序再与这棵DOM树进行交互。

 

c)        代码:

DOM程序:

/*

 * Created on 2004-12-24

 *

 */

package dom;

import org.w 3c .dom.*;

import javax.xml.parsers.*;

import java.io.*;

import org.apache.xerces.parsers.*;

import org.xml.sax.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Test {

    private static int indent = 0;

    public static void main(String[] args) {

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

       try {

            DOMParser parser = new DOMParser();

            parser.parse(new InputSource(new FileReader("1.xml")));

            Document doc = parser.getDocument();

            output(doc);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    public static void output(Node node) {

        int type = node.getNodeType();

        if (type == Node.DOCUMENT_NODE) {

            int length;

            NodeList childs = node.getChildNodes();

            length = childs.getLength();

            for (int i = 0; i < length; i++) {

                output(childs.item(i));

            }

        } else if (type == Node.TEXT_NODE) {

            String value = node.getNodeValue();

            if (!"".equals(value.trim())) {

                emit();

                System.out.println(value);

            }

        } else if (type == Node.ELEMENT_NODE) {

            emit();

            System.out.print("<" + node.getNodeName());

            NamedNodeMap attrs = node.getAttributes();

            int length = attrs.getLength();

            for (int i = 0; i < length; i++) {

                System.out.print(" " + attrs.item(i).getNodeName() + "="

                        + attrs.item(i).getNodeValue());

            }

            System.out.println(">");

            indent++;

            NodeList childs = node.getChildNodes();

            length = childs.getLength();

            for (int i = 0; i < length; i++) {

                output(childs.item(i));

            }

            indent--;

            emit();

            System.out.println("</" + node.getNodeName() + ">");

        }

    }

    public static void emit() {

        for (int i = 0; i < indent; i++)

            System.out.print("/t");

    }

}

 

输出:

<statistic>

     <header>

         <column name="Cache大小">

         </column>

         <column name="Cache命中">

         </column>

         <column name="时间(ms)">

         </column>

     </header>

     <x value="10">

         <y value="493">

         </y>

         <y value="1281">

         </y>

     </x>

     <x value="11">

         <y value="560">

         </y>

         <y value="1063">

         </y>

     </x>

</statistic>

 

注:这个DOM程序的作用就是输出XML文件所对应的DOM树的主要节点。书写DOM程序的重点就在于如何进行对树的遍历,这里最重要的编程技巧就是如何书写递归程序。由于我们采用的时apachexerces解释器,因此上面的DOM程序是使用实现相关的方式。

 

d)        创建树

这里主要演示如何通过程序的方式创建一颗DOM树。以下的程序使用了apachexerces解释器。

创建树的程序:

/*

 * Created on 2004-12-26

 *

 */

package dom;

import org.w 3c .dom.*;

import org.apache.xerces.dom.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Create {

    public static void main(String[] args) {

        DOMImplementation impl = new DOMImplementationImpl();

        Document doc = impl.createDocument(null, "item", null);

        Element e = doc.createElement("name");

        Text t = doc.createTextNode("Hello");

        Element root = doc.getDocumentElement();

        root.setAttribute("id", "nick");

        e.appendChild(t);

        root.appendChild(e);

        Test.output(doc);

    }

}

 

输出:

<item id=nick>

     <name>

         Hello

     </name>

</item>

 

注:在使用程序创建DOM树时。我们可以注意到,我们需要先获得一个DOMImplementationImpl实例,然后在她之上,我们就可以得到DOM树的Document对象,然后在Document之上,我们可以得到所有我们所需要的元素,文本节点,而这也是整个程序所要反映的关键所在。

 

e)        修改树:

在这里主要演示,怎么通过程序的方式来修改DOM树的内容和结构。

修改树的程序:

/*

 * Created on 2004-12-24

 *

 */

package dom;

import org.w 3c .dom.*;

import javax.xml.parsers.*;

import java.io.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Modify {

    public static void main(String[] args) {

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        try {

            DocumentBuilder builder = factory.newDocumentBuilder();

            Document doc = builder.parse(new File("1.xml"));

            Test.output(doc);

            Element root = doc.getDocumentElement();

            NodeList list = root.getElementsByTagName("data");

            Element e = (Element) list.item(0);

            /*    修改节点内容  */

            Text t = (Text) e.getFirstChild();

            t.setData("Hello World");

 

            /*    修改树的结构  */

            NodeList headlist = root.getElementsByTagName("header");

            for (int i = 0; i < headlist.getLength(); i++) {

                root.removeChild(headlist.item(i));

            }

            Test.output(doc);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

 

输出:

之前:

<statistic>

     <header>

         <column name=Cache大小>

         </column>

         <column name=Cache命中>

         </column>

         <column name=时间(ms)>

         </column>

     </header>

     <data>

         <x value=10>

              <y value=493>

              </y>

              <y value=1281>

              </y>

         </x>

         <x value=11>

              <y value=560>

              </y>

              <y value=1063>

              </y>

         </x>

     </data>

</statistic>

 

之后:

<statistic>

     <data>

         Hello World

         <x value=10>

              <y value=493>

              </y>

              <y value=1281>

              </y>

         </x>

         <x value=11>

              <y value=560>

              </y>

              <y value=1063>

              </y>

         </x>

     </data>

</statistic>

 

注:修改树的程序与创建树的程序的区别就在于,我们在修改树的程序中,主要要做的就是先要通过Document实例获得DOM树的DocumentElement,即DOM树的根节点。然后在这以后,我们就可以通过遍历或者查找得到我们要的节点引用,并进行相关操作。这里有一点特别要注意的是,在调用removeChild操作时,两节点之间必须是父子关系。从上述程序当中,我们可以发现DOM 1.0在修改树时,需要非常了解树的整体结构。

 

 

5.   DOM 2.0

DOM 2.0 DOM树上的节点操作,提供了一套更新,更灵活的API

a)        Traversal

Traversal是属于DOM 2.0的一个新功能,他的作用主要就是可以对节点进行遍历。但是由于J2SE并没有提供对Traversal的支持,因此这里只能使用解释器相关的操作。

程序代码:

/*

 * Created on 2004-12-27

 *

 */

package dom;

import java.io.*;

import org.xml.sax.*;

import org.w 3c .dom.*;

import org.apache.xerces.parsers.*;

import org.apache.xerces.dom.*;

import org.w 3c .dom.traversal.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Traversal {

    public static void main(String[] args) {

        try {

            DOMParser parser = new DOMParser();

            parser.parse(new InputSource(new FileReader("1.xml")));

            Document doc = parser.getDocument();

            Element root = doc.getDocumentElement();

            NodeIterator i = ((DocumentTraversal) doc).createNodeIterator(root,

                    NodeFilter.SHOW_ALL, null, true);

            Node node = null;

            while ((node = i.nextNode()) != null) {

                System.out.println(node.getNodeType() + " "

                        + node.getNodeName());

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

 

输出:

1 statistic

3 #text

1 header

3 #text

1 column

3 #text

1 column

3 #text

1 column

3 #text

3 #text

1 data

3 #text

1 x

3 #text

1 y

3 #text

1 y

3 #text

3 #text

1 x

3 #text

1 y

3 #text

1 y

3 #text

3 #text

3 #text

 

注:NodeIterator的作用与Iterator同,里面的元素均是Node,程序可直接在这些Node引用上进行操作。其中createNodeIterator()的第一个参数是开始进行搜索的根位置,第二个是系统预定义的过滤器,第三个是用户自定义的过滤器。其中,用户自定义的过滤器要在系统定义的过滤器之后起作用。第四个是“是否需要展开实体引用”。

DOM 1.0中我们可以通过getElementByName来获取某一名称的节点列表;而在DOM 2.0中我们可以通过Traversal接口达到同样的效果。而Traversal的优点就在于,他的过滤能力比1.0中的getElement要强。因为,在自定义的过滤器当中,我们可以实现很复杂的过滤逻辑,而不仅仅是对名称等有限的,单一的属性过滤。

 

b)        带过滤的Traversal

过滤器:

/*

 * Created on 2004-12-27

 *

 */

package dom;

import org.w 3c .dom.traversal.*;

import org.w 3c .dom.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class TraversalFilter implements NodeFilter {

    public short acceptNode(Node node) {

        if ("header".equals(node.getNodeName().trim()))

            return NodeFilter.FILTER_REJECT;

        else if (node.getNodeType() == Node.ELEMENT_NODE) {

            return NodeFilter.FILTER_ACCEPT;

        } else

            return NodeFilter.FILTER_SKIP;       

    }

}

 

程序代码:

/*

 * Created on 2004-12-27

 *

 */

package dom;

import java.io.*;

import org.xml.sax.*;

import org.w 3c .dom.*;

import org.apache.xerces.parsers.*;

import org.apache.xerces.dom.*;

import org.w 3c .dom.traversal.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Traversal {

    public static void main(String[] args) {

        try {

            DOMParser parser = new DOMParser();

            parser.parse(new InputSource(new FileReader("1.xml")));

            Document doc = parser.getDocument();

            Element root = doc.getDocumentElement();

            NodeIterator i = ((DocumentTraversal) doc).createNodeIterator(root,

                    NodeFilter.SHOW_ALL, new TraversalFilter(), true);

            Node node = null;

            while ((node = i.nextNode()) != null) {

                System.out.println(node.getNodeType() + " "

                        + node.getNodeName());

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

 

输出:

1 statistic

1 column

1 column

1 column

1 data

1 x

1 y

1 y

1 x

1 y

1 y

 

注:NodeFilter只有一个acceptNode()的方法,她的返回值类型是一个short,她的值只有三个NodeFilter.FILTER_SKIP,表示只跳过当前节点,NodeFilter.FILTER_REJECT,表示跳过当前节点及其所有子孙节点,NodeFilter.FILTER_ACCEPT,表示接受当前节点。上述的用户自定义的Filter演示了这三个值的作用,对于名称为header的节点,我们把她的整个子树过滤掉,对于节点类型不是Node.ELEMENT_NODE的节点,我们只是把该节点过滤掉。从上述程序中我们可以看到,通过用户实现方法,和返回特定的short值,我们可以比DOM 1.0提供更加复杂的过滤逻辑。

 

c)        TreeWalker

TreeWalker也是属于DOM 2.0的一个新功能,他的作用也是对节点进行遍历。但是由于J2SE并没有提供对TreeWalker的支持,因此这里只能使用解释器相关的操作。

程序代码:

/*

 * Created on 2004-12-27

 *

 */

package dom;

import java.io.FileReader;

import org.apache.xerces.parsers.DOMParser;

import org.w 3c .dom.*;

import org.w 3c .dom.traversal.*;

import org.xml.sax.InputSource;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Walker {

    public static void main(String[] args) {

        try {

            DOMParser parser = new DOMParser();

            parser.parse(new InputSource(new FileReader("1.xml")));

            Document doc = parser.getDocument();

            Element root = doc.getDocumentElement();

            TreeWalker tw = ((DocumentTraversal) doc).createTreeWalker(root,

                    NodeFilter.SHOW_ELEMENT, null, true);

            Node node = null;

            while ((node = tw.nextNode()) != null) {

                System.out.println(node.getNodeType() + " "

                        + node.getNodeName());

            }

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

 

输出:

1 header

1 column

1 column

1 column

1 data

1 x

1 y

1 y

1 x

1 y

1 y

 

注:在创建TreeWalker实例时调用的createTreeWalker()方法的四个参数的含义与createNodeIterator()同。他们之间的区别是NodeIterator是节点的线性列表。而TreeWalker则是按照树型组织节点。

 

d)        Range

Range也是DOM 2.0提供的一个新功能。他可以通过程序的方式,截取出DOM树中的某一段,然后对该段进行一些特定的操作。

程序代码:

/*

 * Created on 2004-12-27

 *

 */

package dom;

import java.io.FileReader;

import org.apache.xerces.parsers.DOMParser;

import org.w 3c .dom.*;

import org.xml.sax.InputSource;

import org.w 3c .dom.ranges.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class MyRange {

    public static void main(String[] args) {

        try {

            DOMParser parser = new DOMParser();

            parser.parse(new InputSource(new FileReader("1.xml")));

            Document doc = parser.getDocument();

            Element data = (Element) doc.getElementsByTagName("data").item(0);

            Range range = ((DocumentRange) doc).createRange();

            range.setStartBefore(data.getFirstChild());

            range.setEndAfter(data.getLastChild());

            range.deleteContents();

            range.detach();

            Test.output(doc);

        } catch (Exception e) {

        }

    }

}

 

输出:

<statistic>

     <header>

         <column name=Cache大小>

         </column>

         <column name=Cache命中>

         </column>

         <column name=时间(ms)>

         </column>

     </header>

     <data>

     </data>

</statistic>

 

注:上述程序的作用,就是把data的子孙节点设置成一个Range,然后把这个Range整个进行删除。

 

 

 

 

 

 

 

 

 

 

6.   JDOM

JDOM的设计目标,主要就是在模型上对SAXDOM进行统一。

a)        模型:

DOMBuilder b = new DOMBuilder();

Document d = b.build(…);

SAXBuilder b = new SAXBuilder();

Document d = b.build(…);

SAX Builder

DOM Builder

JDOM Document

XML Outputter

SAX Outputter

DOM Outputter

XML Document

DOM Tree

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


b)        模型说明:

从上图可以看到,JDOM主要是通过SAXDOMBuilderXML文件或者已经建立好的DOM树,转化成JDOM的内部Document形式,然后再利用其他的Outputter对这个内部的Document进行输出。

 

c)        代码:

程序代码:

/*

 * Created on 2004-12-27

 *

 */

package jdom;

import java.io.*;

import org.jdom.*;

import org.jdom.input.*;

import org.jdom.output.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Test {

    public static void main(String[] args) {

        try {

            SAXBuilder b = new SAXBuilder();

            Document d = b.build(new File("1.xml"));

            XMLOutputter o = new XMLOutputter();

            Format f = Format.getPrettyFormat();

            f.setEncoding("gb2312");

            o.setFormat(f);

            o.output(d, System.out);

        } catch (Exception e) {}

    }

}

 

输出:

<?xml version="1.0" encoding="gb2312"?>

<statistic>

  <header>

    <column name="Cache大小" />

    <column name="Cache命中" />

    <column name="时间(ms)" />

  </header>

  <data>

    <x value="10">

      <y value="493" />

      <y value="1281" />

    </x>

    <x value="11">

      <y value="560" />

      <y value="1063" />

    </x>

  </data>

</statistic>

 

注:当使用XMLOutputter时,我们需要提供一个输出流,当使用SAXOutputter时,我们需要设定对应的ContentHandler,当使用DOMOutputter时,我们将得到Document节点。所以,总的来说,我认为JDOM的意义更多的是在SAXDOM和流之间的转换。

 

7.   JAXP

正如本文开始部分所说,JAXP的意义就在于他提供一套统一的API,而不管底层使用的是哪个厂商提供的解释器,因此,JAXP的意义与JDBC类似。

a)        SAX解释器:

SAXParserFactory factory = SAXParserFactory.newInstance();

SAXParser parser = factory.newSAXParser();

parser.parse(Input,ContentHandler);

 

b)        DOM解释器:

DocumentBuilderFacotry factory = DocumentBuilderFacotry.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

Document doc = builder.parse(Input);

 

 

8.   XSLT

作为本文的最后部分,这里主要就是介绍一下如何在Java程序中结合XMLXSL文件。

a)        代码:

程序代码:

/*

 * Created on 2004-12-27

 *

 */

package xsl;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.transform.*;

import javax.xml.transform.stream.*;

import javax.xml.transform.dom.*;

import java.io.*;

import org.w 3c .dom.*;

/**

 *

 * @author cenyongh@mails.gscas.ac.cn

 */

public class Test {

    public static void main(String[] args) {

        try {

            DocumentBuilder builder = DocumentBuilderFactory.newInstance()

                    .newDocumentBuilder();

            Document doc = builder.parse(new File("1.xml"));

            DOMSource sor = new DOMSource(doc);

            StreamResult res = new StreamResult(System.out);

            TransformerFactory factory = TransformerFactory.newInstance();

            Transformer t = factory.newTransformer();

            t.transform(sor, res);

        } catch (Exception e) {}

    }

}

 

注:通过与JDOM比较,我们可以看到。当我们不使用XSL文件时,我们也可以很容易的通过Transformer提供的方法,实现从SAXDOM和流之间的转换。如果我们需要引入XSL文件的话,那么在获取新的Transformer实例时,作为参数传递到newTransformer()方法中。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值