Вопрос

быть нежным.

Я пытаюсь использовать javax.xml.transform.transformer, чтобы отформатировать некоторую строку XML для отступов / неспециальных между тегами. Если между тегами нет пробелов, он работает нормально. Если есть, это действует странно. Я выложу пример. Я пытался проследить следующую тему: http://forums.sun.com/thread.jspa?messageId=2054303#2699961.. Отказ Нет успеха.

Код для выполнения:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   factory.setIgnoringElementContentWhitespace(true);
   DocumentBuilder builder = factory.newDocumentBuilder();
   DOMImplementation domImpl = builder.getDOMImplementation();
   DOMImplementationLS ls = (DOMImplementationLS) domImpl.getFeature("LS", "3.0");
   LSInput in = ls.createLSInput();
   in.setByteStream(new ByteArrayInputStream(input.getBytes()));
   LSParser parser = ls.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS,
     "http://www.w3.org/2001/XMLSchema");
   Document xmlInput = parser.parse(in);

   StringWriter stringWriter = new StringWriter();
   StreamResult xmlOutput = new StreamResult(stringWriter);
   TransformerFactory f = TransformerFactory.newInstance();
   f.setAttribute("indent-number", 2);

   Transformer transformer = f.newTransformer();
   transformer.setOutputProperty(OutputKeys.INDENT, "yes");
   transformer.setOutputProperty(OutputKeys.METHOD, "xml");
   transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
   transformer.transform(new DOMSource(xmlInput), xmlOutput);

Если нет прерывания между тегами

input : <tag><nested>    hello   </nested></tag>
output : 
<tag>
  <nested>    hello   </nested>
</tag>

Если есть :

input : <tag>  <nested>    hello   </nested></tag>
output : 
<tag>  <nested>    hello   </nested>
</tag>

JVM 1.6.

Здесь что-то очевидное?

Это было полезно?

Решение

Это должно быть проблемой с реализацией трансформатора. Я создал небольшой класс тестового теста, который читает строку без пробела или разрывов линии в виде XML и создает трансформатор из стилей XSLT (также из строки). Stylesheet указывает, что вдавливание должно произойти. Это в основном другой способ достижения того, с чем вы сделали с transformer.setOutputProperty(OutputKeys.INDENT, "yes");

Вот:

package transformation;

import java.io.StringReader;

import javax.xml.transform.Result;
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;

public class TransformerTest {

    public static void main(String[] args) throws Exception {

        final String xmlSample = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><tag><nested>hello</nested></tag>";
        final String stylesheet = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:output method=\"xml\" version=\"1.0\" indent=\"yes\"/><xsl:template match=\"node()|@*\"><xsl:copy><xsl:apply-templates select=\"node()|@*\"/></xsl:copy></xsl:template></xsl:stylesheet>";

        final TransformerFactory factory = TransformerFactory.newInstance();

        final Source xslSource = new StreamSource(new StringReader(stylesheet));
        final Transformer transformer = factory.newTransformer(xslSource);

        final Source source = new StreamSource(new StringReader(xmlSample));
        final Result result = new StreamResult(System.out);

        transformer.transform(source, result);

    }

}

Теперь любопытная вещь есть, результаты варьируются на основе использования трансформатора. Если я не имею никакой реализации трансформаторной работы на классной патке (используя реализацию по умолчанию в JRE Libs), результатом это:

<?xml version="1.0" encoding="UTF-8"?>
<tag>
<nested>hello</nested>
</tag>

Не правильно, так как тег не отступ.

Затем, добавив недавнюю реализацию XALAN на ClassPath (Xalan.jar and Serializer.jar, все еще используя Jre Parsers / DOM Builders), я получаю это:

<?xml version="1.0" encoding="UTF-8"?><tag>
<nested>hello</nested>
</tag>

Все еще не правильно, первый тег находится на той же линии, что и декларация XML и не отступает.

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

Вид странно, как давние реализации трансформатора все еще имеют такое поведение. Но не так плохо, как когда, когда я заметил, что используя валидатор схемы, привел к атрибутам, сброшенным из «расширенного» выхода XML.

Таким образом, казалось бы, было бы многое сделать об этом, кроме попыток найти другие процессоры и посмотреть, имеют ли у них та же проблема. Может быть, саксон стоит выстрела. Этот отчет об ошибках тоже интересен (это для Java 1.5, однако):http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6296446.

Другие советы

Трансформатор, похоже, не нравится белое пространство, поэтому самое простое решение, кажется, просто удалит его ....

    public String prettyPrintXML(String inXML)  {

       String outXML = inXML;

// The transformer doesn't like white space between tags so remove it.          
           String[] bits = inXML.split(">");      
       inXML="";
       boolean first = true;
       for (int n=0;n<bits.length; n++){
           if (first)
            inXML = inXML + bits[n].trim();
           else
             inXML = inXML + ">"+bits[n].trim();

           first = false;
       }
      inXML = inXML + ">";

Передайте inxml в свой трансформатор и выйди.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top