使用 Apache Batik 更正 SVG 文件的缩进(漂亮的打印)

Correct indentation (pretty print) of an SVG file with Apache Batik

我需要了解 apache batik 如何缩进库生成的 SVG 文件。 我有以下代码:

DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();

        String svgNS = "http://www.w3.org/2000/svg";
        Document document = domImpl.createDocument(svgNS, "svg", null);

        SVGGeneratorContext ctx = SVGGeneratorContext.createDefault(document);

        SVGGraphics2D svgGenerator = new SVGGraphics2D(ctx, false);

        for(Drawable savedDrawable : cVwDrawLocal.getSavedDrawables()){
            if(savedDrawable instanceof GeoDrawable){
                savedDrawable.copyToGraphics(svgGenerator);
            }
        }

        boolean useCSS = true; // we want to use CSS style attributes

        String svgFile = svgFileName + ".svg";

        try {
            OutputStream outputStream = new FileOutputStream(svgFile);
            Writer outputStreamWriter = new OutputStreamWriter(outputStream, "UTF-8");
            svgGenerator.stream(outputStreamWriter, useCSS);
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

生成的 SVG 文件为:

<g
  ><g style="fill:white; stroke-miterlimit:1; stroke-dasharray:1; stroke-dashoffset:1; stroke:white;"
    ><line y2="432" style="fill:none;" x1="873" x2="873" y1="432"
    /></g
    ><g style="fill:rgb(0,252,253); stroke-miterlimit:1; stroke-dasharray:0.1,5; stroke-width:2; stroke-dashoffset:1; stroke:rgb(0,252,253);"
    ><line y2="479" style="fill:none;" x1="901" x2="910" y1="490"
    /></g
    >

但我需要这样的东西:

<g>
    <g style="fill:white; stroke-miterlimit:1; stroke-dasharray:1; stroke-dashoffset:1; stroke:white;">
        <line y2="432" style="fill:none;" x1="873" x2="873" y1="432"/>
    </g>
    <g style="fill:rgb(0,252,253); stroke-miterlimit:1; stroke-dasharray:0.1,5; stroke-width:2; stroke-dashoffset:1; stroke:rgb(0,252,253);">
        <line y2="479" style="fill:none;" x1="901" x2="910" y1="490"/>
    </g>
</g>

我怎样才能得到这个? 提前致谢!

好的。我找到了适合我的解决方案:

public static boolean prettyPrintXml(File newFile) {

        try {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setValidating(false);
            documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.parse(newFile);

            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");

            StreamResult streamResult = new StreamResult(newFile);
            DOMSource domSource = new DOMSource(document);
            transformer.transform(domSource, streamResult);
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }

        return true;
    }

谢谢!

注意,漂亮的打印会导致不同的输出,例如如果文本标签内有不同的 tspan 标签。换行符和缩进字符导致视觉空白。

<text x="20" y="20"><tspan>abc</tspan><tspan>def</tspan></text>

不同于

<text x="20" y="20">
   <tspan>abc</tspan>
   <tspan>def</tspan>
</text>

第一个结果:abcdef,第二个结果:abc def