From eab2c0d20d48ba3009de838799945034cbfef34d Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Thu, 22 Jan 2015 07:24:01 +0000 Subject: [PATCH] Add a developer-tool to pretty-print the XMLs in an OOXML file. This makes it easier to compare OOXML files produced by different applications with differeing XML formatting. git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1653777 13f79535-47bb-0310-9956-ffa450edef68 --- .../java/org/apache/poi/dev/OOXMLLister.java | 2 +- .../org/apache/poi/dev/OOXMLPrettyPrint.java | 131 ++++++++++++++++++ 2 files changed, 132 insertions(+), 1 deletion(-) create mode 100644 src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java diff --git a/src/ooxml/java/org/apache/poi/dev/OOXMLLister.java b/src/ooxml/java/org/apache/poi/dev/OOXMLLister.java index ed5fec285..ae418b3cd 100644 --- a/src/ooxml/java/org/apache/poi/dev/OOXMLLister.java +++ b/src/ooxml/java/org/apache/poi/dev/OOXMLLister.java @@ -110,7 +110,7 @@ public class OOXMLLister { public static void main(String[] args) throws Exception { if(args.length == 0) { System.err.println("Use:"); - System.err.println("\tjava HXFLister "); + System.err.println("\tjava OOXMLLister "); System.exit(1); } diff --git a/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java b/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java new file mode 100644 index 000000000..aab811287 --- /dev/null +++ b/src/ooxml/java/org/apache/poi/dev/OOXMLPrettyPrint.java @@ -0,0 +1,131 @@ +/* ==================================================================== + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +==================================================================== */ +package org.apache.poi.dev; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Enumeration; +import java.util.zip.ZipEntry; +import java.util.zip.ZipException; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import org.w3c.dom.Document; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Reads a zipped OOXML file and produces a copy with the included + * pretty-printed XML files. + * + * This is useful for comparing OOXML files produced by different tools as the often + * use different formatting of the XML. + */ +public class OOXMLPrettyPrint { + private final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + private final DocumentBuilder documentBuilder; + + public OOXMLPrettyPrint() throws ParserConfigurationException { + documentBuilder = documentBuilderFactory.newDocumentBuilder(); + } + + public static void main(String[] args) throws Exception { + if(args.length <= 1 || args.length % 2 != 0) { + System.err.println("Use:"); + System.err.println("\tjava OOXMLPrettyPrint [ ] ..."); + System.exit(1); + } + + for(int i = 0;i < args.length;i+=2) { + File f = new File(args[i]); + if(! f.exists()) { + System.err.println("Error, file not found!"); + System.err.println("\t" + f.toString()); + System.exit(2); + } + + handleFile(f, new File(args[i+1])); + } + System.out.println("Done."); + } + + private static void handleFile(File file, File outFile) throws ZipException, + IOException, FileNotFoundException, SAXException, + TransformerException, ParserConfigurationException { + System.out.println("Reading zip-file " + file + " and writing pretty-printed XML to " + outFile); + + ZipFile zipFile = new ZipFile(file); + try { + ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(outFile))); + try { + new OOXMLPrettyPrint().handle(zipFile, out); + } finally { + out.close(); + } + } finally { + zipFile.close(); + + System.out.println(); + } + } + + private void handle(ZipFile file, ZipOutputStream out) throws SAXException, IOException, TransformerException { + Enumeration entries = file.entries(); + while(entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + + out.putNextEntry(new ZipEntry(entry.getName())); + try { + Document document = documentBuilder.parse(new InputSource(file.getInputStream(entry))); + pretty(document, out, 2); + } finally { + out.closeEntry(); + } + System.out.print("."); + } + } + + private static void pretty(Document document, OutputStream outputStream, int indent) throws TransformerException { + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + if (indent > 0) { + // set properties to indent the resulting XML nicely + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", Integer.toString(indent)); + } + Result result = new StreamResult(outputStream); + Source source = new DOMSource(document); + transformer.transform(source, result); + } +}