2016-04-11 4 views
1

Ich habe ein Projekt, das JAXB Marshalled XML-Dateien verwendet, um Konfigurationsstatus verschiedener Umgebungen zu vergleichen. Mir ist aufgefallen, dass es bei der Implementierung des JAXB-Marshallers unter Windows einige Unterschiede zu der Unix-Version geben muss. Wenn ich zwei auf den verschiedenen Plattformen erstellte Dateien vergleiche, zeigt mein Vergleichswerkzeug immer einen Unterschied am Ende der Datei an. Die unter Windows erstellte Datei hat am Ende der Datei eine neue Zeile (CR und LF), während sie in der Unix-Version nicht vorhanden ist.Marshaller unter Windows fügt neue Zeile am Ende der Datei hinzu

Bitte beachten Sie, dass das Problem nicht über den Unterschied der neuen Zeilenzeichen zwischen beiden Plattformen ist! Der Windows-Marshaller fügt effektiv eine "neue Zeile" am Ende der Datei hinzu, während der Unix-Marshaller nach dem schließenden ">" des Root-Tags stoppt.

Windows marshaller adds a new line at the end

Gibt es einen Parameter I auf den Einweiser, um diese zusätzliche Leitung zu verhindern passieren kann oder muss ich es explizit entfernen, nachdem auf Windows Rangier-, so dass mein Vergleichs-Tool nicht den Unterschied Flagge tut ?

Dies ist, wie der Rangier-Code wie folgt aussieht:

public void marshal(final Object rootObject, final OutputStream outputStream) throws JAXBException, TransformerException { 
    Preconditions.checkArgument(rootObject != null, "rootObject must not be null"); 
    Preconditions.checkArgument(outputStream != null, "outputStream must not be null"); 
    final JAXBContext ctx = JAXBContext.newInstance(rootObject.getClass()); 
    final Document document = getFactories().newDocument(); 
    document.setXmlStandalone(true); 
    final Marshaller marshaller = ctx.createMarshaller(); 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
    marshaller.setSchema(schema); 
    marshaller.marshal(rootObject, document); 
    createTransformer().transform(new DOMSource(document), new StreamResult(outputStream)); 
    } 

    public static Transformer createTransformer() { 
    final Transformer transformer = getFactories().newTransformer(); 
    transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
    transformer.setOutputProperty(OutputKeys.STANDALONE, "yes"); 
    transformer.setOutputProperty(OutputKeys.ENCODING, JAXBDefaults.OUTPUT_CHARSET.name()); 
    transformer.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, CDATA_XML_ELEMENTS); 
    transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", IDENT_LENGTH); 
    return transformer; 
    } 


    private static class JAXBFactories { 

    private DocumentBuilderFactory documentBuilderFactory; 

    public DocumentBuilderFactory getDocumentBuilderFactory() { 
     if (documentBuilderFactory == null) { 
     documentBuilderFactory = DocumentBuilderFactory.newInstance(); 
     } 
     return documentBuilderFactory; 
    } 

    private DocumentBuilder documentBuilder; 

    public DocumentBuilder getDocumentBuilder() { 
     if (documentBuilder == null) { 
     try { 
      documentBuilder = getDocumentBuilderFactory().newDocumentBuilder(); 
     } catch (final ParserConfigurationException ex) { 
      throw new RuntimeException("Failed to create DocumentBuilder", ex); 
     } 
     } 
     return documentBuilder; 
    } 

    public Document newDocument() { 
     return getDocumentBuilder().newDocument(); 
    } 

    private TransformerFactory transformerFactory; 

    public TransformerFactory getTransformerFactory() { 
     if (transformerFactory == null) { 
     transformerFactory = TransformerFactory.newInstance(); 
     } 
     return transformerFactory; 
    } 

    public Transformer newTransformer() { 
     try { 
     return getTransformerFactory().newTransformer(); 
     } catch (final TransformerConfigurationException ex) { 
     throw new RuntimeException("Failed to create Transformer", ex); 
     } 
    } 

    } 

    private static class FactoriesHolder { 

    static final JAXBFactories FACTORIES = new JAXBFactories(); 
    } 

    private static JAXBFactories getFactories() { 
    return FactoriesHolder.FACTORIES; 
    } 

Antwort

1

Es gibt keinen Grund (oder Erwartung), die ziemlich Druck XML genau die gleichen Ergebnisse aus zwei unterschiedlichen Systemen produzieren. Es scheint jedoch wahrscheinlich, dass, wenn Sie das hübsche Drucken ausgeschaltet haben (und Ihre IDE/Editor dies tun lassen), Sie wahrscheinlich feststellen werden, dass die Ausgabe die gleiche ist.

Pretty-Drucken von XML ist eine Transformation des Originals, das Layout hinzufügt. Es ist nicht mehr real xml.

+0

Danke für die Antwort! Ich verstehe Ihren Standpunkt. Mein Problem ist jedoch, dass einer der Hauptgründe, warum ich XML gewählt habe, die menschliche Lesbarkeit ist, die es bietet, und die Möglichkeit, leicht mit jedem Vergleichstool zu vergleichen. Jetzt, wegen dieser zusätzlichen Zeile, erhalte ich viele falsche Unterschiede, wenn ich mehrere Dateien gleichzeitig vergleiche. Sie kennen kein gutes Werkzeug für den XML-Vergleich, oder? :) Klartext Vergleich funktioniert jetzt gut, aber es gibt viele andere Probleme abgesehen von diesem neuen Zeilenproblem. – Alex

+0

@Alex - [KDiff] (http://kdiff3.sourceforge.net/) kann gesagt werden, Leerzeichen während des Vergleichs zu ignorieren. Dies löst nicht alle Probleme, aber es hilft sehr. – OldCurmudgeon

Verwandte Themen