How to pretty print XML from Java?

后端 未结 30 2469
慢半拍i
慢半拍i 2020-11-22 01:55

I have a Java String that contains XML, with no line feeds or indentations. I would like to turn it into a String with nicely formatted XML. How do I do this?



        
30条回答
  •  清酒与你
    2020-11-22 02:48

    I have found that in Java 1.6.0_32 the normal method to pretty print an XML string (using a Transformer with a null or identity xslt) does not behave as I would like if tags are merely separated by whitespace, as opposed to having no separating text. I tried using in my template to no avail. The simplest solution I found was to strip the space the way I wanted using a SAXSource and XML filter. Since my solution was for logging I also extended this to work with incomplete XML fragments. Note the normal method seems to work fine if you use a DOMSource but I did not want to use this because of the incompleteness and memory overhead.

    public static class WhitespaceIgnoreFilter extends XMLFilterImpl
    {
    
        @Override
        public void ignorableWhitespace(char[] arg0,
                                        int arg1,
                                        int arg2) throws SAXException
        {
            //Ignore it then...
        }
    
        @Override
        public void characters( char[] ch,
                                int start,
                                int length) throws SAXException
        {
            if (!new String(ch, start, length).trim().equals("")) 
                   super.characters(ch, start, length); 
        }
    }
    
    public static String prettyXML(String logMsg, boolean allowBadlyFormedFragments) throws SAXException, IOException, TransformerException
        {
            TransformerFactory transFactory = TransformerFactory.newInstance();
            transFactory.setAttribute("indent-number", new Integer(2));
            Transformer transformer = transFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            StringWriter out = new StringWriter();
            XMLReader masterParser = SAXHelper.getSAXParser(true);
            XMLFilter parser = new WhitespaceIgnoreFilter();
            parser.setParent(masterParser);
    
            if(allowBadlyFormedFragments)
            {
                transformer.setErrorListener(new ErrorListener()
                {
                    @Override
                    public void warning(TransformerException exception) throws TransformerException
                    {
                    }
    
                    @Override
                    public void fatalError(TransformerException exception) throws TransformerException
                    {
                    }
    
                    @Override
                    public void error(TransformerException exception) throws TransformerException
                    {
                    }
                });
            }
    
            try
            {
                transformer.transform(new SAXSource(parser, new InputSource(new StringReader(logMsg))), new StreamResult(out));
            }
            catch (TransformerException e)
            {
                if(e.getCause() != null && e.getCause() instanceof SAXParseException)
                {
                    if(!allowBadlyFormedFragments || !"XML document structures must start and end within the same entity.".equals(e.getCause().getMessage()))
                    {
                        throw e;
                    }
                }
                else
                {
                    throw e;
                }
            }
            out.flush();
            return out.toString();
        }
    

提交回复
热议问题