【问题标题】:Serialize DOM to FileOutputStream using Xerces使用 Xerces 将 DOM 序列化为 FileOutputStream
【发布时间】:2012-01-05 15:55:23
【问题描述】:

我正在使用this 链接使用 DOM 生成 XML 文件。它说“Xerces 解析器与 JDK 1.5 发行版捆绑在一起。因此您无需单独下载解析器。”

但是,当我在 Eclipse Helios 中编写以下行时,即使我的系统中有 Java 1.6,它也会出现编译时错误。

import org.apache.xml.serialize.XMLSerializer;

为什么会这样?

【问题讨论】:

    标签: java xml dom xerces


    【解决方案1】:

    Xerces 确实与 JDK 捆绑在一起,但您应该将它与 javax.xml.parsers 下的 JAXP API 一起使用。检查下面程序的输出。

    此外,要序列化 ​​XML Document,您应该使用 DOM 级别 3 加载和保存(存在于 JDK 中)或没有样式表的 XSLT 转换(身份转换)。其余的取决于特定的实现。 Xerces XMLSerializer 已弃用:

    已弃用。此类在 Xerces 2.9.0 中已弃用。建议新应用程序使用 DOM Level 3 LSSerializer 或 JAXP 的 XML 转换 API (TrAX) 来序列化 XML。有关详细信息,请参阅 Xerces 文档。

    这是一个使用 DOM 级别 3 的序列化示例:

    import org.w3c.dom.*;
    import org.w3c.dom.bootstrap.DOMImplementationRegistry;
    import org.w3c.dom.ls.*;
    
    public class DOMExample3 {
    
        public static void main(String[] args) throws Exception {
            DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();    
            DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("XML 3.0 LS 3.0");
            if (impl == null) {
                System.out.println("No DOMImplementation found !");
                System.exit(0);
            }
    
            System.out.printf("DOMImplementationLS: %s\n", impl.getClass().getName());
    
            LSParser parser = impl.createLSParser(
                    DOMImplementationLS.MODE_SYNCHRONOUS,
                    "http://www.w3.org/TR/REC-xml");
            // http://www.w3.org/2001/XMLSchema
            System.out.printf("LSParser: %s\n", parser.getClass().getName());
    
            if (args.length == 0) {
                System.exit(0);
            }
    
            Document doc = parser.parseURI(args[0]);
    
            LSSerializer serializer = impl.createLSSerializer();
            LSOutput output = impl.createLSOutput();
            output.setEncoding("UTF-8");
            output.setByteStream(System.out);
            serializer.write(doc, output);
            System.out.println();
        }
    }
    

    这是一个身份转换的例子:

    import org.w3c.dom.Document;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.transform.OutputKeys;
    import javax.xml.transform.Result;
    import javax.xml.transform.Source;
    import javax.xml.transform.Transformer;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.DOMSource;
    import javax.xml.transform.stream.StreamResult;
    import javax.xml.transform.stream.StreamSource;
    
    public class DOMExample2 {
        public static void main(String[] args) throws Exception {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder parser = factory.newDocumentBuilder();
    
            System.out.println("Parsing XML document...");
            Document doc;
            doc = parser.parse(args[0]);
    
            // Xerces Java 2
    
            /* Deprecated. This class was deprecated in Xerces 2.9.0.
             * It is recommended that new applications use the DOM Level 3
             * LSSerializer or JAXP's Transformation API for XML (TrAX)
             * for serializing XML and HTML.
             * See the Xerces documentation for more information.
             */  
            /*
            System.out.println("XERCES: Displaying XML document...");
            OutputFormat of = new OutputFormat(doc, "ISO-8859-1", true);
            PrintWriter pw = new PrintWriter(System.out);
            BaseMarkupSerializer bms = new XMLSerializer(pw, of);
            bms.serialize(doc);
    */
            // JAXP
    
            System.out.println("JAXP: Displaying XML document...");
            TransformerFactory transFactory = TransformerFactory.newInstance();
            System.out.println(transFactory.getClass().getName());
            //transFactory.setAttribute("indent-number", 2);
            Transformer idTransform = transFactory.newTransformer();
            idTransform.setOutputProperty(OutputKeys.METHOD, "xml");
            idTransform.setOutputProperty(OutputKeys.INDENT,"yes");
            // Apache default indentation is 0
            idTransform.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");                
            Source input = new DOMSource(doc);
            Result output = new StreamResult(System.out);
            idTransform.transform(input, output);
        }
    }
    

    【讨论】:

    • 如果您认为它可能被视为答案,您可以标记它吗?
    • 我通过点击“这个答案很有用”增加了计数:)
    • 基于此制作了一些 Eclipse 详细格式化程序:gist.github.com/xkr47/9595446
    【解决方案2】:

    它将在 IIRC,com.sun.org.apache.xml.serialize.XMLSerializer。但是,这些是私人课程,可能随时更改。我建议改用标准的公共 API(javax.* 和朋友)。 (使用不带任何 XSLT 的转换 API。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 1970-01-01
      • 2011-05-31
      • 1970-01-01
      • 2011-04-03
      • 2011-01-19
      相关资源
      最近更新 更多