Как отформатировать XML-файл - PullRequest
1 голос
/ 12 декабря 2011

У меня есть метод, который возвращает String с отформатированным XML.Метод читает XML-файл из файла на сервере и анализирует его в строку:

По сути, метод в настоящее время:

  private ServletConfig config;
  InputStream xmlIn = null ;
  xmlIn = config.getServletContext().getResourceAsStream(filename + ".xml") ; 
  String xml = IOUtils.toString(xmlIn);
  IOUtils.closeQuietly(xmlIn);
  return xml;  

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

Что я имею в виду под форматированным xml - это что-то вроде:

<xml>
  <root>
    <elements>
       <elem1/>
       <elem2/>
    <elements>
  <root>
</xml>

И что я имею в виду под неформатированным xml - что-то вроде:

<xml><root><elements><elem1/><elem2/><elements><root></xml>

или:

<xml>
<root>
<elements>
<elem1/>
<elem2/>
<elements>
<root>
</xml>

Есть ли простой способ сделать это?

Ответы [ 6 ]

1 голос
/ 12 декабря 2011

Попробуйте что-то вроде следующего:

TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(
    new StreamSource(new StringReader(
        "<xsl:stylesheet version=\"1.0\"" +
        "   xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" + 
        "<xsl:output method=\"xml\" omit-xml-declaration=\"yes\"/>" +
        "  <xsl:strip-space elements=\"*\"/>" + 
        "  <xsl:template match=\"@*|node()\">" +
        "   <xsl:copy>" +
        "    <xsl:apply-templates select=\"@*|node()\"/>" +
        "   </xsl:copy>" +
        "  </xsl:template>" +
        "</xsl:stylesheet>"
    ))
);
Source source = new StreamSource(new StringReader("xml string here"));
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);

Вместо источника, являющегося StreamSource во втором случае, оно также может быть DOMSource, если у вас в памяти Document, если вы хотите изменить DOM перед сохранением.

DOMSource source = new DOMSource(document);

Чтобы прочитать файл XML в объект Document:

File file = new File("c:\\MyXMLFile.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(file);
doc.getDocumentElement().normalize();

Наслаждайтесь:)

1 голос
/ 12 декабря 2011

Удалите все символы новой строки с String xml = IOUtils.toString(xmlIn).replace("\n", "").Или \t, чтобы сохранить несколько строк, но без отступа.

0 голосов
/ 12 декабря 2011

пустой преобразователь с параметром, устанавливающим параметры отступа следующим образом:

public static String getStringFromDocument(Document dom, boolean indented) {
    String signedContent = null;        
    try {
            StringWriter sw = new StringWriter();
            DOMSource domSource = new DOMSource(dom);
            TransformerFactory tf = new TransformerFactoryImpl();
            Transformer trans = tf.newTransformer();
            trans = tf.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
            trans.setOutputProperty(OutputKeys.INDENT, indented ? "yes" : "no");

            trans.transform(domSource, new StreamResult(sw));
            sw.flush();
            signedContent = sw.toString();

        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return signedContent;
    }

у меня работает.

ключ лежит в этой строке

 trans.setOutputProperty(OutputKeys.INDENT, indented ? "yes" : "no");
0 голосов
/ 12 декабря 2011

, если вы уверены, что отформатирован xml как:

<xml>
  <root>
    <elements>
       <elem1/>
       <elem2/>
    <elements>
  <root>
</xml>

Вы можете заменить всю группу 1 в ^(\s*)< на "". таким образом, текст в XML не будет изменен.

0 голосов
/ 12 декабря 2011

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

JAXBContext jc = JAXBContext.newInstance(packageName);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
m.marshal(element, outputStream);

Довольно много времени, чтобы добраться доэтот этап, хотя ... возможно, хороший вариант, если у вас уже есть твердый xsd

0 голосов
/ 12 декабря 2011

Вы можете: 1) удалить все последовательные пробелы (но не один пробел), а затем заменить все> (пробелы) <на> < применимо, только если полезный контент не имеет нескольких последовательных значимых пробелов 2) прочитать его в каком-нибудь дереве и сериализовать, используя некрасивую сериализацию

    SAXReader reader = new SAXReader();
    Reader r = new StringReader(data);
    Document document = reader.read(r);
    OutputFormat format = OutputFormat.createCompactFormat();
    StringWriter sw = new StringWriter();
    XMLWriter writer = new XMLWriter(sw, format);
    writer.write(document);
    String string = writer.toString();

3) используйте канонизация (но вы должны как-то объяснить ему, что те пробелы, которые вы хотите удалить, незначительны)

...