Пишите Довольно XML-содержимое в файле с использованием Java [duplicate]

с моей стороны, я думаю, что вы можете, но вам придется делать файлы для подключения к базе данных, потому что mysqli_* будет принимать только mysqli_connect, и поэтому с помощью mysql_*

вы можете попробовать при обучении PDO Better

394
задан w5m 5 July 2013 в 17:04
поделиться

30 ответов

Теперь 2012 и Java могут делать больше, чем с XML, я бы хотел добавить альтернативу моему принятому ответу. Это не имеет зависимостей вне Java 6.

import org.w3c.dom.Node;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;

import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;

/**
 * Pretty-prints xml, supplied as a string.
 * <p/>
 * eg.
 * <code>
 * String formattedXml = new XmlFormatter().format("<tag><nested>hello</nested></tag>");
 * </code>
 */
public class XmlFormatter {

    public String format(String xml) {

        try {
            final InputSource src = new InputSource(new StringReader(xml));
            final Node document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement();
            final Boolean keepDeclaration = Boolean.valueOf(xml.startsWith("<?xml"));

        //May need this: System.setProperty(DOMImplementationRegistry.PROPERTY,"com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl");


            final DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
            final DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
            final LSSerializer writer = impl.createLSSerializer();

            writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE); // Set this to true if the output needs to be beautified.
            writer.getDomConfig().setParameter("xml-declaration", keepDeclaration); // Set this to true if the declaration is needed to be outputted.

            return writer.writeToString(document);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        String unformattedXml =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><QueryMessage\n" +
                        "        xmlns=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message\"\n" +
                        "        xmlns:query=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query\">\n" +
                        "    <Query>\n" +
                        "        <query:CategorySchemeWhere>\n" +
                        "   \t\t\t\t\t         <query:AgencyID>ECB\n\n\n\n</query:AgencyID>\n" +
                        "        </query:CategorySchemeWhere>\n" +
                        "    </Query>\n\n\n\n\n" +
                        "</QueryMessage>";

        System.out.println(new XmlFormatter().format(unformattedXml));
    }
}
90
ответ дан DaoWen 21 August 2018 в 12:41
поделиться
  • 1
    Нет отступ, но он работает с этим: System.setProperty (DOMImplementationRegistry.PROPERTY, «com.sun.org.apache.xerces.internal.dom.DOMImplementationSourceImpl»); – ggb667 20 March 2013 в 14:21
  • 2
    Как добавить отступ в этот пример? – ggb667 20 March 2013 в 14:22
  • 3
    Отлично работал для меня как есть. Использование Java 6. – Lee Meador 12 June 2013 в 15:55
  • 4
    @DanTemple Кажется, вам нужно использовать LSOutput для управления кодировкой. См. chipkillmar.net/2009/03/25/pretty-print-xml-from-a-dom – Joshua Davis 12 March 2014 в 21:50
  • 5
    Я попытался использовать это в Android, но я не могу найти пакет `DOMImplementationRegistry. Я использую java 8. – Chintan Soni 10 May 2015 в 07:53

Еще одно решение, которое работает для нас

import java.io.StringWriter;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

**
 * Pretty Print XML String
 * 
 * @param inputXmlString
 * @return
 */
public static String prettyPrintXml(String xml) {

    final StringWriter sw;

    try {
        final OutputFormat format = OutputFormat.createPrettyPrint();
        final org.dom4j.Document document = DocumentHelper.parseText(xml);
        sw = new StringWriter();
        final XMLWriter writer = new XMLWriter(sw, format);
        writer.write(document);
    }
    catch (Exception e) {
        throw new RuntimeException("Error pretty printing xml:\n" + xml, e);
    }
    return sw.toString();
}
3
ответ дан Anand 21 August 2018 в 12:41
поделиться

есть очень хорошая утилита xml командной строки, которая называется xmlstarlet ( http://xmlstar.sourceforge.net/ ), которая может делать много вещей, которые многие люди используют.

Вы можете выполнить эту программу программно, используя Runtime.exec, а затем прочитать форматированный выходной файл.

скачать xmlstarlet: http://sourceforge.net/project/showfiles.php?group_id=66612&package_id&hl=ru = 64589

0
ответ дан anjanb 21 August 2018 в 12:41
поделиться

Использование jdom2: http://www.jdom.org/

import java.io.StringReader;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

String prettyXml = new XMLOutputter(Format.getPrettyFormat()).
                         outputString(new SAXBuilder().build(new StringReader(uglyXml)));
1
ответ дан BijanE 21 August 2018 в 12:41
поделиться

Я видел один ответ с помощью Scala, так что вот еще один из Groovy, на всякий случай кто-то считает его интересным. Отступ по умолчанию - 2 шага, конструктор XmlNodePrinter может быть передан еще одно значение.

def xml = "<tag><nested>hello</nested></tag>"
def stringWriter = new StringWriter()
def node = new XmlParser().parseText(xml);
new XmlNodePrinter(new PrintWriter(stringWriter)).print(node)
println stringWriter.toString()

Использование Java, если groovy jar находится в classpath

  String xml = "<tag><nested>hello</nested></tag>";
  StringWriter stringWriter = new StringWriter();
  Node node = new XmlParser().parseText(xml);
  new XmlNodePrinter(new PrintWriter(stringWriter)).print(node);
  System.out.println(stringWriter.toString());
116
ответ дан Community 21 August 2018 в 12:41
поделиться
  • 1
    Это код, который я всегда использовал, но в этой компании это не сработало, я предполагаю, что они используют другую XML-трансформирующую библиотеку. Я создал завод как отдельную строку, а затем сделал factory.setAttribute("indent-number", 4);, и теперь он работает. – Adrian Smith 21 October 2010 в 14:25
  • 2
    Как сделать так, чтобы выход не содержал <?xml version="1.0" encoding="UTF-8"?>? – Thang Pham 19 July 2011 в 20:13
  • 3
    @Harry: transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); – jjmontes 7 October 2011 в 10:06
  • 4
    Спасибо, вот что я искал. Если у вас есть XML, уже разбирающийся с XOM в «Документе», объект, вы можете передать его непосредственно в serializer.write (document); – Thibault D. 13 August 2013 в 07:07
  • 5
    Привет, я использую этот точный код, а мои форматы правильно за исключением первого элемента. Итак, это: <?xml version="1.0" encoding="UTF-8"?><root> все в одной строке. Любые идеи почему? – CodyK 10 March 2015 в 19:28
  • 6
    где repeatString (stack ++); способ ..? – user1912935 25 June 2015 в 09:59
  • 7
    private static String repeatString (int stack) {StringBuilder indent = new StringBuilder (); for (int i = 0; i & lt; stack; i ++) {indent.append (& quot;); } return indent.toString (); } – codeskraps 25 June 2015 в 14:16
  • 8
    @Codemiester: Кажется, это ошибка (см. stackoverflow.com/a/18251901/3375325 ). Добавление transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); работало для меня. – lazlev 10 August 2016 в 16:53

В случае, если вам не нужно отступать так много, но несколько разрывов строк, этого может быть достаточно просто для регулярного выражения ...

String leastPrettifiedXml = uglyXml.replaceAll("><", ">\n<");

Код хороший, а не результат из-за отсутствия отступа ,


(Для решений с отступом см. другие ответы.)

0
ответ дан comonad 21 August 2018 в 12:41
поделиться
  • 1
    Хмммм ... Просто подумал громко, кому нужно такое решение? Только область, которую я вижу, - это данные, которые мы получаем из некоторых веб-сервисов, и просто для проверки того, что данные и ее действительность, разработчик или тестер могут нуждаться в таких легких. В противном случае это не хороший вариант .... – Sudhakar Chavali 8 February 2018 в 17:22
  • 2
    @SudhakarChavali Я разработчик. мне может понадобиться это для грязных println () и log.debug () hacks; то есть несколько раз я могу использовать только файлы журналов из ограниченной серверной среды (с интерфейсом веб-администратора вместо доступа к оболочке) вместо разумной пошаговой отладки программы. – comonad 19 February 2018 в 18:23

Кевин Хакансон сказал: «Однако, если вы знаете, что ваша строка XML действительна, и вы не хотите брать накладные расходы на разбор строки в DOM, тогда выполните преобразование по DOM, чтобы получить строку обратно - вы можете просто сделать какой-то старомодный персонаж с помощью синтаксического анализа символов. Вставьте новую строку и пробелы после каждого символа, счетчика keep и indent (чтобы определить количество пробелов), которое вы увеличиваете для каждого & lt; ...> и декремента для каждого пользователя см. "

Согласовано. Такой подход намного быстрее и имеет гораздо меньше зависимостей.

Пример решения:

/**
 * XML utils, including formatting.
 */
public class XmlUtils
{
  private static XmlFormatter formatter = new XmlFormatter(2, 80);

  public static String formatXml(String s)
  {
    return formatter.format(s, 0);
  }

  public static String formatXml(String s, int initialIndent)
  {
    return formatter.format(s, initialIndent);
  }

  private static class XmlFormatter
  {
    private int indentNumChars;
    private int lineLength;
    private boolean singleLine;

    public XmlFormatter(int indentNumChars, int lineLength)
    {
      this.indentNumChars = indentNumChars;
      this.lineLength = lineLength;
    }

    public synchronized String format(String s, int initialIndent)
    {
      int indent = initialIndent;
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i < s.length(); i++)
      {
        char currentChar = s.charAt(i);
        if (currentChar == '<')
        {
          char nextChar = s.charAt(i + 1);
          if (nextChar == '/')
            indent -= indentNumChars;
          if (!singleLine)   // Don't indent before closing element if we're creating opening and closing elements on a single line.
            sb.append(buildWhitespace(indent));
          if (nextChar != '?' && nextChar != '!' && nextChar != '/')
            indent += indentNumChars;
          singleLine = false;  // Reset flag.
        }
        sb.append(currentChar);
        if (currentChar == '>')
        {
          if (s.charAt(i - 1) == '/')
          {
            indent -= indentNumChars;
            sb.append("\n");
          }
          else
          {
            int nextStartElementPos = s.indexOf('<', i);
            if (nextStartElementPos > i + 1)
            {
              String textBetweenElements = s.substring(i + 1, nextStartElementPos);

              // If the space between elements is solely newlines, let them through to preserve additional newlines in source document.
              if (textBetweenElements.replaceAll("\n", "").length() == 0)
              {
                sb.append(textBetweenElements + "\n");
              }
              // Put tags and text on a single line if the text is short.
              else if (textBetweenElements.length() <= lineLength * 0.5)
              {
                sb.append(textBetweenElements);
                singleLine = true;
              }
              // For larger amounts of text, wrap lines to a maximum line length.
              else
              {
                sb.append("\n" + lineWrap(textBetweenElements, lineLength, indent, null) + "\n");
              }
              i = nextStartElementPos - 1;
            }
            else
            {
              sb.append("\n");
            }
          }
        }
      }
      return sb.toString();
    }
  }

  private static String buildWhitespace(int numChars)
  {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < numChars; i++)
      sb.append(" ");
    return sb.toString();
  }

  /**
   * Wraps the supplied text to the specified line length.
   * @lineLength the maximum length of each line in the returned string (not including indent if specified).
   * @indent optional number of whitespace characters to prepend to each line before the text.
   * @linePrefix optional string to append to the indent (before the text).
   * @returns the supplied text wrapped so that no line exceeds the specified line length + indent, optionally with
   * indent and prefix applied to each line.
   */
  private static String lineWrap(String s, int lineLength, Integer indent, String linePrefix)
  {
    if (s == null)
      return null;

    StringBuilder sb = new StringBuilder();
    int lineStartPos = 0;
    int lineEndPos;
    boolean firstLine = true;
    while(lineStartPos < s.length())
    {
      if (!firstLine)
        sb.append("\n");
      else
        firstLine = false;

      if (lineStartPos + lineLength > s.length())
        lineEndPos = s.length() - 1;
      else
      {
        lineEndPos = lineStartPos + lineLength - 1;
        while (lineEndPos > lineStartPos && (s.charAt(lineEndPos) != ' ' && s.charAt(lineEndPos) != '\t'))
          lineEndPos--;
      }
      sb.append(buildWhitespace(indent));
      if (linePrefix != null)
        sb.append(linePrefix);

      sb.append(s.substring(lineStartPos, lineEndPos + 1));
      lineStartPos = lineEndPos + 1;
    }
    return sb.toString();
  }

  // other utils removed for brevity
}
9
ответ дан David Easley 21 August 2018 в 12:41
поделиться
  • 1
    Благодаря! Только это работало для меня (в среде JSF). – Daniel Szalay 1 May 2011 в 17:11
  • 2
    Так оно и должно быть сделано. Формат «на лету» на уровне строк. Это единственное решение, которое будет форматировать недействительный или неполный XML. – Florian F 26 October 2017 в 10:20

Все вышеперечисленные решения не сработали для меня, тогда я нашел это http://myshittycode.com/2014/02/10/java-properly-indenting-xml-string/

Ключ удаляет пробелы с XPath

    String xml = "<root>" +
             "\n   " +
             "\n<name>Coco Puff</name>" +
             "\n        <total>10</total>    </root>";

try {
    Document document = DocumentBuilderFactory.newInstance()
            .newDocumentBuilder()
            .parse(new InputSource(new ByteArrayInputStream(xml.getBytes("utf-8"))));

    XPath xPath = XPathFactory.newInstance().newXPath();
    NodeList nodeList = (NodeList) xPath.evaluate("//text()[normalize-space()='']",
                                                  document,
                                                  XPathConstants.NODESET);

    for (int i = 0; i < nodeList.getLength(); ++i) {
        Node node = nodeList.item(i);
        node.getParentNode().removeChild(node);
    }

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

    StringWriter stringWriter = new StringWriter();
    StreamResult streamResult = new StreamResult(stringWriter);

    transformer.transform(new DOMSource(document), streamResult);

    System.out.println(stringWriter.toString());
}
catch (Exception e) {
    e.printStackTrace();
}
4
ответ дан Georgy Gobozov 21 August 2018 в 12:41
поделиться
  • 1
    Обратите внимание, что использование свойства '{ xml.apache.org/xslt } indent-amount привяжет вас к конкретной реализации трансформатора. – vallismortis 17 June 2015 в 14:28
  • 2
    Из всех решений эта работа работала лучше всего. У меня были пробелы и новые строки уже в моем XML, и я не хотел добавлять больше зависимостей в свой проект. Мне жаль, что мне не нужно разбирать XML, но хорошо. – Fabio 10 March 2016 в 20:25
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
//initialize StreamResult with File object to save to file
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
transformer.transform(source, result);
String xmlString = result.getWriter().toString();
System.out.println(xmlString);

Примечание. Результаты могут различаться в зависимости от версии Java. Поиск обходных решений, характерных для вашей платформы.

227
ответ дан Jean-François Savard 21 August 2018 в 12:41
поделиться
  • 1
    Как сделать так, чтобы выход не содержал <?xml version="1.0" encoding="UTF-8"?>? – Thang Pham 19 July 2011 в 20:26
  • 2
    Значение по умолчанию: 0. Добавить transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); – David Blevins 19 February 2012 в 00:25
  • 3
    Чтобы пропустить объявление <?xml ...>, добавьте transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes") – rustyx 25 August 2015 в 20:01
  • 4
    Случайные читатели могут найти полезную улучшенную версию описанного здесь решения ( stackoverflow.com/a/33541820/363573 ). – Stephan 5 November 2015 в 11:20
  • 5
  • 6
    это было, как, 10 лет, пусть это идет, у вас уже есть правильный ответ где-то здесь. вы даже сами написали , так в чем же смысл? – Lorenzo Boccaccia 14 July 2018 в 17:33

Я обнаружил, что в Java 1.6.0_32 нормальный метод для правильной печати строки XML (с использованием Transformer с нулем или идентификатором xslt) не ведет себя так, как хотелось бы, если теги просто разделенные пробелами, в отличие от отсутствия разделительного текста. Я пробовал использовать <xsl:strip-space elements="*"/> в своем шаблоне безрезультатно. Самое простое решение, которое я нашел, это разделить пространство так, как я хотел, используя фильтр SAXSource и XML. Поскольку мое решение предназначено для ведения журнала, я также расширил его, чтобы работать с неполными фрагментами XML. Обратите внимание, что обычный метод работает нормально, если вы используете DOMSource, но я не хотел использовать его из-за неполноты и издержек памяти.

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();
    }
0
ответ дан JFK 21 August 2018 в 12:41
поделиться

Поскольку вы начинаете с String, перед тем, как использовать Transformer, вам нужно скрывать объект DOM (например, Node). Однако, если вы знаете, что ваша строка XML действительна и вы не хотите нести накладные расходы на память при разборе строки в DOM, тогда запустите преобразование по DOM, чтобы получить строку обратно - вы могли бы просто сделать несколько старомодных символьный синтаксический анализ. Вставьте новую строку и пробелы после каждого символа </...>, счетчик keep и indent (чтобы определить количество пробелов), которые вы увеличиваете для каждого <...> и уменьшаетесь для каждого </...>, который вы видите.

Отказ от ответственности - Я сделал вырезание / вставку / редактирование текста ниже, поэтому они не могут компилироваться как есть.

public static final Element createDOM(String strXML) 
    throws ParserConfigurationException, SAXException, IOException {

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setValidating(true);
    DocumentBuilder db = dbf.newDocumentBuilder();
    InputSource sourceXML = new InputSource(new StringReader(strXML))
    Document xmlDoc = db.parse(sourceXML);
    Element e = xmlDoc.getDocumentElement();
    e.normalize();
    return e;
}

public static final void prettyPrint(Node xml, OutputStream out)
    throws TransformerConfigurationException, TransformerFactoryConfigurationError, TransformerException {
    Transformer tf = TransformerFactory.newInstance().newTransformer();
    tf.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    tf.setOutputProperty(OutputKeys.INDENT, "yes");
    tf.transform(new DOMSource(xml), new StreamResult(out));
}
12
ответ дан Kevin Hakanson 21 August 2018 в 12:41
поделиться
  • 1
    & quot; Однако, если вы знаете, что ваша строка XML действительна ... & quot; хорошая точка зрения. См. Мое решение, основанное на этом подходе ниже. – David Easley 27 May 2010 в 11:51

Просто обратите внимание, что для наивысшего ответа требуется использование xerces.

Если вы не хотите добавлять эту внешнюю зависимость, вы можете просто использовать стандартные библиотеки jdk (которые фактически построены с использованием xerces внутренне).

NB Была ошибка с jdk версии 1.5, см. http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6296446 , но она разрешена сейчас.,

( Обратите внимание, что если произошла ошибка, это вернет исходный текст)

package com.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.stream.StreamResult;

import org.xml.sax.InputSource;

public class XmlTest {
    public static void main(String[] args) {
        XmlTest t = new XmlTest();
        System.out.println(t.formatXml("<a><b><c/><d>text D</d><e value='0'/></b></a>"));
    }

    public String formatXml(String xml){
        try{
            Transformer serializer= SAXTransformerFactory.newInstance().newTransformer();
            serializer.setOutputProperty(OutputKeys.INDENT, "yes");
            //serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            serializer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
            //serializer.setOutputProperty("{http://xml.customer.org/xslt}indent-amount", "2");
            Source xmlSource=new SAXSource(new InputSource(new ByteArrayInputStream(xml.getBytes())));
            StreamResult res =  new StreamResult(new ByteArrayOutputStream());            
            serializer.transform(xmlSource, res);
            return new String(((ByteArrayOutputStream)res.getOutputStream()).toByteArray());
        }catch(Exception e){
            //TODO log error
            return xml;
        }
    }

}
51
ответ дан khylo 21 August 2018 в 12:41
поделиться
  • 1
    В этом случае левые вкладки не используются. Все теги начинаются с первого символа строки, как обычный текст. – Ruslan 23 December 2010 в 10:57
  • 2
    вам не нужно указывать кодировку при преобразовании между байтами и строкой? – Will Glass 2 December 2011 в 03:18
  • 3
    Не должно быть необходимости конвертировать из и в байт-массивы / String. По крайней мере, вам нужно будет указать кодировку при этом. Лучше будет использовать классы StringReader и StringWriter, включенные в InputSource и StreamResult. – maximdim 21 December 2012 в 18:00
  • 4
    не работает. вам нужно возиться с некоторой внутренней реестре. – user1050755 17 November 2014 в 18:14
  • 5
    Вот более простой вариант этого решения: stackoverflow.com/a/33541820/363573 – Stephan 5 November 2015 в 11:37

У меня была такая же проблема, и у меня был большой успех с JTidy ( http://jtidy.sourceforge.net/index.html )

Пример:

Tidy t = new Tidy();
t.setIndentContent(true);
Document d = t.parseDOM(
    new ByteArrayInputStream("HTML goes here", null);

OutputStream out = new ByteArrayOutputStream();
t.pprint(d, out);
String html = out.toString();
1
ответ дан Kristoffer Lindvall 21 August 2018 в 12:41
поделиться
  • 1
    Работает ли jTidy для чистого XML, или это только для (X) HTML? – khylo 17 December 2010 в 17:32
  • 2
    Кажется, не работает для чистого XML. Только HTMLS. – BeepDog 29 June 2011 в 20:38

Этот код ниже работает отлично

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

String formattedXml1 = prettyFormat("<root><child>aaa</child><child/></root>");

public static String prettyFormat(String input) {
    return prettyFormat(input, "2");
}

public static String prettyFormat(String input, String indent) {
    Source xmlInput = new StreamSource(new StringReader(input));
    StringWriter stringWriter = new StringWriter();
    try {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", indent);
        transformer.transform(xmlInput, new StreamResult(stringWriter));

        String pretty = stringWriter.toString();
        pretty = pretty.replace("\r\n", "\n");
        return pretty;              
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
3
ответ дан maks tkach 21 August 2018 в 12:41
поделиться
  • 1
    Пожалуйста, объясните, почему ваш код работает для OP – techspider 2 June 2016 в 18:51

Просто для справки в будущем, вот решение, которое сработало для меня (спасибо комментарию, что @George Hawkins опубликовал в одном из ответов):

DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
LSSerializer writer = impl.createLSSerializer();
writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
LSOutput output = impl.createLSOutput();
ByteArrayOutputStream out = new ByteArrayOutputStream();
output.setByteStream(out);
writer.write(document, output);
String xmlStr = new String(out.toByteArray());
7
ответ дан Michael 21 August 2018 в 12:41
поделиться

Если вы уверены, что у вас есть правильный XML, этот простой и избегает XML DOM-деревьев. Может быть, есть некоторые ошибки, прокомментируйте, если вы видите что-нибудь

public String prettyPrint(String xml) {
            if (xml == null || xml.trim().length() == 0) return "";

            int stack = 0;
            StringBuilder pretty = new StringBuilder();
            String[] rows = xml.trim().replaceAll(">", ">\n").replaceAll("<", "\n<").split("\n");

            for (int i = 0; i < rows.length; i++) {
                    if (rows[i] == null || rows[i].trim().length() == 0) continue;

                    String row = rows[i].trim();
                    if (row.startsWith("<?")) {
                            // xml version tag
                            pretty.append(row + "\n");
                    } else if (row.startsWith("</")) {
                            // closing tag
                            String indent = repeatString("    ", --stack);
                            pretty.append(indent + row + "\n");
                    } else if (row.startsWith("<")) {
                            // starting tag
                            String indent = repeatString("    ", stack++);
                            pretty.append(indent + row + "\n");
                    } else {
                            // tag data
                            String indent = repeatString("    ", stack);
                            pretty.append(indent + row + "\n");
                    }
            }

            return pretty.toString().trim();
    }
4
ответ дан milosmns 21 August 2018 в 12:41
поделиться
  • 1
    где метод repeatString ..? – user1912935 25 June 2015 в 11:07
  • 2
    private static String repeatString (int stack) {StringBuilder indent = new StringBuilder (); for (int i = 0; i & lt; stack; i ++) {indent.append (& quot;); } return indent.toString (); } – codeskraps 25 June 2015 в 14:17
  • 3
    Да [user1912935], что написал @codeskraps, должен быть достаточно простым :) – milosmns 25 June 2015 в 16:36
  • 4
    Конкатенация с помощью StringBuilder внутри цикла: плохая практика. – james.garriss 22 December 2015 в 15:00

В прошлом я довольно печально использовал метод org.dom4j.io.OutputFormat.createPrettyPrint ()

public String prettyPrint(final String xml){  

    if (StringUtils.isBlank(xml)) {
        throw new RuntimeException("xml was null or blank in prettyPrint()");
    }

    final StringWriter sw;

    try {
        final OutputFormat format = OutputFormat.createPrettyPrint();
        final org.dom4j.Document document = DocumentHelper.parseText(xml);
        sw = new StringWriter();
        final XMLWriter writer = new XMLWriter(sw, format);
        writer.write(document);
    }
    catch (Exception e) {
        throw new RuntimeException("Error pretty printing xml:\n" + xml, e);
    }
    return sw.toString();
}
28
ответ дан mlo55 21 August 2018 в 12:41
поделиться

Хммм ... столкнулся с чем-то вроде этого, и это известная ошибка ... просто добавьте этот OutputProperty ..

transformer.setOutputProperty(OutputPropertiesFactory.S_KEY_INDENT_AMOUNT, "8");

Надеюсь, это поможет ...

10
ответ дан rzymek 21 August 2018 в 12:41
поделиться

Попробуйте следующее:

 try
                    {
                        TransformerFactory transFactory = TransformerFactory.newInstance();
                        Transformer transformer = null;
                        transformer = transFactory.newTransformer();
                        StringWriter buffer = new StringWriter();
                        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
                        transformer.transform(new DOMSource(element),
                                  new StreamResult(buffer)); 
                        String str = buffer.toString();
                        System.out.println("XML INSIDE IS #########################################"+str);
                        return element;
                    }
                    catch (TransformerConfigurationException e)
                    {
                        e.printStackTrace();
                    }
                    catch (TransformerException e)
                    {
                        e.printStackTrace();
                    }
0
ответ дан Sireesh Yarlagadda 21 August 2018 в 12:41
поделиться

Что касается комментария, что «вы должны сначала построить дерево DOM»: Нет, вам не нужно и не должно этого делать.

Вместо этого создайте StreamSource (новый StreamSource (новый StringReader (str)), и передать это упомянутому идентификатору трансформатора.Это будет использовать синтаксический анализатор SAX, и результат будет намного быстрее. Построение промежуточного дерева - это чистые накладные расходы для этого случая. В противном случае ответ верхнего уровня хорош.

7
ответ дан StaxMan 21 August 2018 в 12:41
поделиться
  • 1
    Я с полным основанием согласен: построение промежуточного дерева DOM является пустой тратой памяти. Thansk для этого ответа. – Florian F 26 October 2017 в 10:18

Вот ответ на мой вопрос.

Нет никаких гарантий относительно того, как он реагирует на недопустимые XML или большие документы.

package ecb.sdw.pretty;

import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

/**
 * Pretty-prints xml, supplied as a string.
 * <p/>
 * eg.
 * <code>
 * String formattedXml = new XmlFormatter().format("<tag><nested>hello</nested></tag>");
 * </code>
 */
public class XmlFormatter {

    public XmlFormatter() {
    }

    public String format(String unformattedXml) {
        try {
            final Document document = parseXmlFile(unformattedXml);

            OutputFormat format = new OutputFormat(document);
            format.setLineWidth(65);
            format.setIndenting(true);
            format.setIndent(2);
            Writer out = new StringWriter();
            XMLSerializer serializer = new XMLSerializer(out, format);
            serializer.serialize(document);

            return out.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private Document parseXmlFile(String in) {
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            InputSource is = new InputSource(new StringReader(in));
            return db.parse(is);
        } catch (ParserConfigurationException e) {
            throw new RuntimeException(e);
        } catch (SAXException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        String unformattedXml =
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><QueryMessage\n" +
                        "        xmlns=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message\"\n" +
                        "        xmlns:query=\"http://www.SDMX.org/resources/SDMXML/schemas/v2_0/query\">\n" +
                        "    <Query>\n" +
                        "        <query:CategorySchemeWhere>\n" +
                        "   \t\t\t\t\t         <query:AgencyID>ECB\n\n\n\n</query:AgencyID>\n" +
                        "        </query:CategorySchemeWhere>\n" +
                        "    </Query>\n\n\n\n\n" +
                        "</QueryMessage>";

        System.out.println(new XmlFormatter().format(unformattedXml));
    }

}
127
ответ дан Steve McLeod 21 August 2018 в 12:41
поделиться
  • 1
    Просто отметим, что для этого ответа требуется использование Xerces. Если вы не хотите добавлять эту зависимость, вы можете просто использовать стандартные библиотеки jdk и javax.xml.transform.Transformer (см. Мой ответ ниже) – khylo 17 December 2010 в 17:28
  • 2
    Еще в 2008 году это был хороший ответ, но теперь все это можно сделать со стандартными классами JDK, а не с классами Apache. См. xerces.apache.org/xerces2-j/faq-general.html#faq-6 . Да, это FAQ по Xerces, но ответ охватывает стандартные классы JDK. Первоначальная реализация этих классов у 1.5 была много, но все отлично работает с 1,6. Скопируйте пример LSSerializer в FAQ, нарежьте & quot; ... & quot; бит и добавить writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE); после строки LSSerializer writer = .... – George Hawkins 4 May 2011 в 09:43
  • 3
    Я создал небольшой класс, используя пример Apache, который @GeorgeHawkins дал ссылку. Не хватало того, как была инициализирована переменная document, поэтому я подумал, что могу добавить замедление и сделать из нее быстрый пример. Дайте мне знать, если что-то изменить, pastebin.com/XL7932aC – samwell 16 July 2012 в 17:52
  • 4
    это неправда, что вы можете сделать это только с помощью jdk. по крайней мере, не надежно. это зависит от некоторой внутренней реализации реестра, которая по умолчанию не работает с моим jdk7u72. поэтому вы все равно лучше используете материал apache. – user1050755 17 November 2014 в 18:16
  • 5
    Это решение работало для меня на Java 1.7. – John 23 September 2015 в 17:31

Я должен был сначала найти эту страницу, прежде чем придумать свое решение! Во всяком случае, my использует рекурсию Java для анализа XML-страницы. Этот код полностью автономный и не зависит от сторонних библиотек. Также .. он использует рекурсию!

// you call this method passing in the xml text
public static void prettyPrint(String text){
    prettyPrint(text, 0);
}

// "index" corresponds to the number of levels of nesting and/or the number of tabs to print before printing the tag
public static void prettyPrint(String xmlText, int index){
    boolean foundTagStart = false;
    StringBuilder tagChars = new StringBuilder();
    String startTag = "";
    String endTag = "";
    String[] chars = xmlText.split("");
    // find the next start tag
    for(String ch : chars){
        if(ch.equalsIgnoreCase("<")){
            tagChars.append(ch);
            foundTagStart = true;
        } else if(ch.equalsIgnoreCase(">") && foundTagStart){
            startTag = tagChars.append(ch).toString();
            String tempTag = startTag;
            endTag = (tempTag.contains("\"") ? (tempTag.split(" ")[0] + ">") : tempTag).replace("<", "</"); // <startTag attr1=1 attr2=2> => </startTag>
            break;
        } else if(foundTagStart){
            tagChars.append(ch);
        }
    }
    // once start and end tag are calculated, print start tag, then content, then end tag
    if(foundTagStart){
        int startIndex = xmlText.indexOf(startTag);
        int endIndex = xmlText.indexOf(endTag);
        // handle if matching tags NOT found
        if((startIndex < 0) || (endIndex < 0)){
            if(startIndex < 0) {
                // no start tag found
                return;
            } else {
                // start tag found, no end tag found (handles single tags aka "<mytag/>" or "<?xml ...>")
                printTabs(index);
                System.out.println(startTag);
                // move on to the next tag
                // NOTE: "index" (not index+1) because next tag is on same level as this one
                prettyPrint(xmlText.substring(startIndex+startTag.length(), xmlText.length()), index);
                return;
            }
        // handle when matching tags found
        } else {
            String content = xmlText.substring(startIndex+startTag.length(), endIndex);
            boolean isTagContainsTags = content.contains("<"); // content contains tags
            printTabs(index);
            if(isTagContainsTags){ // ie: <tag1><tag2>stuff</tag2></tag1>
                System.out.println(startTag);
                prettyPrint(content, index+1); // "index+1" because "content" is nested
                printTabs(index);
            } else {
                System.out.print(startTag); // ie: <tag1>stuff</tag1> or <tag1></tag1>
                System.out.print(content);
            }
            System.out.println(endTag);
            int nextIndex = endIndex + endTag.length();
            if(xmlText.length() > nextIndex){ // if there are more tags on this level, continue
                prettyPrint(xmlText.substring(nextIndex, xmlText.length()), index);
            }
        }
    } else {
        System.out.print(xmlText);
    }
}

private static void printTabs(int counter){
    while(counter-- > 0){ 
        System.out.print("\t");
    }
}
0
ответ дан Steve T 21 August 2018 в 12:41
поделиться

Использование scala:

import xml._
val xml = XML.loadString("<tag><nested>hello</nested></tag>")
val formatted = new PrettyPrinter(150, 2).format(xml)
println(formatted)

Вы можете сделать это и на Java, если вы зависите от scala-library.jar. Это выглядит так:

import scala.xml.*;

public class FormatXML {
    public static void main(String[] args) {
        String unformattedXml = "<tag><nested>hello</nested></tag>";
        PrettyPrinter pp = new PrettyPrinter(150, 3);
        String formatted = pp.format(XML.loadString(unformattedXml), TopScope$.MODULE$);
        System.out.println(formatted);
    }
}

Объект PrettyPrinter сконструирован с двумя ints, первая - макс длина строки, а вторая - шаг отступа.

17
ответ дан Synesso 21 August 2018 в 12:41
поделиться

Для тех, кто ищет быстрое и грязное решение, для которого XML не должен быть 100% действительным. например в случае регистрации REST / SOAP (вы никогда не знаете, что посылают другие, -))

Я нашел и переработал код, который был отключен Я нашел онлайн, который, как мне кажется, по-прежнему отсутствует в качестве допустимого возможного подхода: / g1]

public static String prettyPrintXMLAsString(String xmlString) {
    /* Remove new lines */
    final String LINE_BREAK = "\n";
    xmlString = xmlString.replaceAll(LINE_BREAK, "");
    StringBuffer prettyPrintXml = new StringBuffer();
    /* Group the xml tags */
    Pattern pattern = Pattern.compile("(<[^/][^>]+>)?([^<]*)(</[^>]+>)?(<[^/][^>]+/>)?");
    Matcher matcher = pattern.matcher(xmlString);
    int tabCount = 0;
    while (matcher.find()) {
        String str1 = (null == matcher.group(1) || "null".equals(matcher.group())) ? "" : matcher.group(1);
        String str2 = (null == matcher.group(2) || "null".equals(matcher.group())) ? "" : matcher.group(2);
        String str3 = (null == matcher.group(3) || "null".equals(matcher.group())) ? "" : matcher.group(3);
        String str4 = (null == matcher.group(4) || "null".equals(matcher.group())) ? "" : matcher.group(4);

        if (matcher.group() != null && !matcher.group().trim().equals("")) {
            printTabs(tabCount, prettyPrintXml);
            if (!str1.equals("") && str3.equals("")) {
                ++tabCount;
            }
            if (str1.equals("") && !str3.equals("")) {
                --tabCount;
                prettyPrintXml.deleteCharAt(prettyPrintXml.length() - 1);
            }

            prettyPrintXml.append(str1);
            prettyPrintXml.append(str2);
            prettyPrintXml.append(str3);
            if (!str4.equals("")) {
                prettyPrintXml.append(LINE_BREAK);
                printTabs(tabCount, prettyPrintXml);
                prettyPrintXml.append(str4);
            }
            prettyPrintXml.append(LINE_BREAK);
        }
    }
    return prettyPrintXml.toString();
}

private static void printTabs(int count, StringBuffer stringBuffer) {
    for (int i = 0; i < count; i++) {
        stringBuffer.append("\t");
    }
}

public static void main(String[] args) {
    String x = new String(
            "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap:Body><soap:Fault><faultcode>soap:Client</faultcode><faultstring>INVALID_MESSAGE</faultstring><detail><ns3:XcbSoapFault xmlns=\"\" xmlns:ns3=\"http://www.someapp.eu/xcb/types/xcb/v1\"><CauseCode>20007</CauseCode><CauseText>INVALID_MESSAGE</CauseText><DebugInfo>Problems creating SAAJ object model</DebugInfo></ns3:XcbSoapFault></detail></soap:Fault></soap:Body></soap:Envelope>");
    System.out.println(prettyPrintXMLAsString(x));
}

здесь - выход:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
        <faultcode>soap:Client</faultcode>
        <faultstring>INVALID_MESSAGE</faultstring>
        <detail>
            <ns3:XcbSoapFault xmlns="" xmlns:ns3="http://www.someapp.eu/xcb/types/xcb/v1">
                <CauseCode>20007</CauseCode>
                <CauseText>INVALID_MESSAGE</CauseText>
                <DebugInfo>Problems creating SAAJ object model</DebugInfo>
            </ns3:XcbSoapFault>
        </detail>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>
0
ответ дан Tim 21 August 2018 в 12:41
поделиться

Решения, которые я нашел здесь для Java 1.6+, не переформатируют код, если он уже отформатирован. Тот, который работал для меня (и отформатировал уже отформатированный код), был следующим.

import org.apache.xml.security.c14n.CanonicalizationException;
import org.apache.xml.security.c14n.Canonicalizer;
import org.apache.xml.security.c14n.InvalidCanonicalizerException;
import org.w3c.dom.Element;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.io.IOException;
import java.io.StringReader;

public class XmlUtils {
    public static String toCanonicalXml(String xml) throws InvalidCanonicalizerException, ParserConfigurationException, SAXException, CanonicalizationException, IOException {
        Canonicalizer canon = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
        byte canonXmlBytes[] = canon.canonicalize(xml.getBytes());
        return new String(canonXmlBytes);
    }

    public static String prettyFormat(String input) throws TransformerException, ParserConfigurationException, IOException, SAXException, InstantiationException, IllegalAccessException, ClassNotFoundException {
        InputSource src = new InputSource(new StringReader(input));
        Element document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src).getDocumentElement();
        Boolean keepDeclaration = input.startsWith("<?xml");
        DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance();
        DOMImplementationLS impl = (DOMImplementationLS) registry.getDOMImplementation("LS");
        LSSerializer writer = impl.createLSSerializer();
        writer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
        writer.getDomConfig().setParameter("xml-declaration", keepDeclaration);
        return writer.writeToString(document);
    }
}

Это хороший инструмент для использования в ваших модульных тестах для полномасштабного сравнения xml.

private void assertXMLEqual(String expected, String actual) throws ParserConfigurationException, IOException, SAXException, CanonicalizationException, InvalidCanonicalizerException, TransformerException, IllegalAccessException, ClassNotFoundException, InstantiationException {
    String canonicalExpected = prettyFormat(toCanonicalXml(expected));
    String canonicalActual = prettyFormat(toCanonicalXml(actual));
    assertEquals(canonicalExpected, canonicalActual);
}
0
ответ дан Wojtek 21 August 2018 в 12:41
поделиться

В качестве альтернативы ответам max , codeskraps , David Easley и milosmns , посмотрите в моей легкой, высокопроизводительной библиотеке довольно-печатных: xml-formatter

// construct lightweight, threadsafe, instance
PrettyPrinter prettyPrinter = PrettyPrinterBuilder.newPrettyPrinter().build();

StringBuilder buffer = new StringBuilder();
String xml = ..; // also works with char[] or Reader

if(prettyPrinter.process(xml, buffer)) {
     // valid XML, print buffer
} else {
     // invalid XML, print xml
}

Иногда, например, при запуске издевающихся SOAP-сервисов непосредственно из файла, хорошо иметь pretty-printer, который также обрабатывает уже довольно печатный XML:

PrettyPrinter prettyPrinter = PrettyPrinterBuilder.newPrettyPrinter().ignoreWhitespace().build();

Как некоторые комментировали, довольно-печатная версия - это просто способ представления XML в более удобочитаемой форме - пробелы строго не принадлежат в ваших XML-данных.

Библиотека предназначена для красивой печати для целей ведения журнала, а также включает функции фильтрации (удаление / анонимизация поддерева) и довольно-типографию XML в узлах CDATA и Text.

116
ответ дан Community 21 August 2018 в 12:41
поделиться
  • 1
    Это код, который я всегда использовал, но в этой компании это не сработало, я предполагаю, что они используют другую XML-трансформирующую библиотеку. Я создал завод как отдельную строку, а затем сделал factory.setAttribute("indent-number", 4);, и теперь он работает. – Adrian Smith 21 October 2010 в 14:25
  • 2
    Как сделать так, чтобы выход не содержал <?xml version="1.0" encoding="UTF-8"?>? – Thang Pham 19 July 2011 в 20:13
  • 3
    @Harry: transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); – jjmontes 7 October 2011 в 10:06
  • 4
    Спасибо, вот что я искал. Если у вас есть XML, уже разбирающийся с XOM в «Документе», объект, вы можете передать его непосредственно в serializer.write (document); – Thibault D. 13 August 2013 в 07:07
  • 5
    Привет, я использую этот точный код, а мои форматы правильно за исключением первого элемента. Итак, это: <?xml version="1.0" encoding="UTF-8"?><root> все в одной строке. Любые идеи почему? – CodyK 10 March 2015 в 19:28
  • 6
    где repeatString (stack ++); способ ..? – user1912935 25 June 2015 в 09:59
  • 7
    private static String repeatString (int stack) {StringBuilder indent = new StringBuilder (); for (int i = 0; i & lt; stack; i ++) {indent.append (& quot;); } return indent.toString (); } – codeskraps 25 June 2015 в 14:16
  • 8
    @Codemiester: Кажется, это ошибка (см. stackoverflow.com/a/18251901/3375325 ). Добавление transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "yes"); работало для меня. – lazlev 10 August 2016 в 16:53

Вот как это сделать, используя dom4j :

Импорт:

import org.dom4j.Document;  
import org.dom4j.DocumentHelper;  
import org.dom4j.io.OutputFormat;  
import org.dom4j.io.XMLWriter;

Код:

String xml = "<your xml='here'/>";  
Document doc = DocumentHelper.parseText(xml);  
StringWriter sw = new StringWriter();  
OutputFormat format = OutputFormat.createPrettyPrint();  
XMLWriter xw = new XMLWriter(sw, format);  
xw.write(doc);  
String result = sw.toString();
17
ответ дан Synesso 21 August 2018 в 12:41
поделиться
117
ответ дан Community 1 November 2018 в 06:27
поделиться
1
ответ дан user3083990 1 November 2018 в 06:27
поделиться
117
ответ дан Community 1 November 2018 в 06:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: