代码之家  ›  专栏  ›  技术社区  ›  RahulD

用Java程序用XSLT转换多个XML/XTML/HTML文件

  •  0
  • RahulD  · 技术社区  · 14 年前

    我想使用多个输入文件(XML/HTML/XHTML)和相应的XSLT来为相应的输入文件生成输出文件。如果只有一个输入XML文件和一个输入XSLT文件,那么通过下面的程序,我可以成功地转换它。 例如,在给定程序中,我的输入(X)HTML文件是temp.HTML,输入XSLT是temp.xsl,它产生的输出是temp_copy.HTML。 如果我有两个或多个输入文件temp1.html和temp2.html以及相应的XSLT temp1.xsl和temp2.xsl,那么如何使用相应的输入文件生成输出temp1_copy.html和temp2_copy.html? 谢谢你!

    我当前的Java代码:

     public class SimpleXSLT {
        public static void main(String[] args) {
    
            String inXML = "C:/tmp/temp.html";
            String inXSL = "C:/tmp/temp.xsl";
            String outTXT = "C:/tmp/temp_copy.html";
            SimpleXSLT st = new SimpleXSLT();
            try {
                st.transform(inXML,inXSL,outTXT);
                } catch(TransformerConfigurationException e) {
                System.err.println("Invalid factory configuration");
                System.err.println(e);
                } catch(TransformerException e) {
                System.err.println("Error during transformation");
                System.err.println(e);
            }
        }
        public void transform(String inXML,String inXSL,String outTXT)
        throws TransformerConfigurationException,
        TransformerException {
            TransformerFactory factory = TransformerFactory.newInstance();
            StreamSource xslStream = new StreamSource(inXSL);
            Transformer transformer = factory.newTransformer(xslStream);
            transformer.setErrorListener(new MyErrorListener());
            StreamSource in = new StreamSource(inXML);
            StreamResult out = new StreamResult(outTXT);
            transformer.transform(in,out);
            System.out.println("The generated XML file is:" + outTXT);
        }
    }
    class MyErrorListener implements ErrorListener {
        public void warning(TransformerException e)
        throws TransformerException {
            show("Warning",e);
            throw(e);
        }
        public void error(TransformerException e)
        throws TransformerException {
            show("Error",e);
            throw(e);
        }
        public void fatalError(TransformerException e)
        throws TransformerException {
            show("Fatal Error",e);
            throw(e);
        }
        private void show(String type,TransformerException e) {
            System.out.println(type + ": " + e.getMessage());
            if(e.getLocationAsString() != null)
            System.out.println(e.getLocationAsString());
        }
    }
    
    1 回复  |  直到 14 年前
        1
  •  2
  •   Michael Kay    14 年前

    您正在使用JAXP转换API,也称为TrAX,所以让我们坚持下去。如果您转向XSLT2.0和Saxon,那么使用Saxon的s9api API会更好,但只要您不需要高级2.0功能,Saxon也支持TrAX。

    在TrAX中,表示“已编译”样式表的对象是Templates对象。因此,您可以使用TransformerFactory.newTemplates()编译样式表,然后可以重复使用此Templates对象来转换多个源文档。Templates.newTransformer()为您提供了一个可以用于执行转换的转换器。事实上,您可以重复使用transformer(串行而非并行)来执行多个转换,但我的建议是每次都使用一个新的transformer。重用模板是您获得性能优势的地方;Templates对象也是线程安全的。

    至于1.0与2.0。对于许多简单的转换来说,1.0已经足够了,但您很快就会发现自己在做分组或字符串操作之类的事情,这些事情在2.0中要容易得多。由于Java平台(即Saxon)有一个广泛使用的开源XSLT 2.0处理器,并且有兼容的API,所以现在使用XSLT 1.0的理由真的很少。

    很多人错误地认为样式表上的version属性是用来选择XSLT1.0或2.0处理器的。通常情况并非如此(可能在某些IDE(如XMLSpy)中除外)。相反,它是用来通知处理器作者编写的XSLT规范的版本。如果你说version=“1.0”并选择2.0处理器,那么它将以一种“怪癖”模式运行,试图与XSLT1.0最大限度地兼容,例如,即使在添加两个整数时,它也会使用浮点运算。相反,当您说version=“2.0”并选择1.0处理器时,处理器会在遇到不理解的语言构造时尝试采取回退操作,而不是将其视为编译时错误而拒绝。