Entfernen Sie 'standalone = "yes"' aus dem generierten XML

82

Kennen Sie eine JAXB-Einstellung, um zu verhindern, dass im resultierenden XML Standalone = "yes" generiert wird?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
Johan Pelgrim
quelle
7
Warum ist das ein Problem?
Kornel
@Kornel in meinem Projekt, dass, um mit Tibco und WebMethod verwendet zu werden, es Fehler erzeugen wird, weil Standalone = Ja nicht erkannt wird
aswzen

Antworten:

61

Diese Liegenschaft:

marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", false);

... kann verwendet werden, um keine zu haben:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

Ich würde diese bewährte Methode jedoch nicht in Betracht ziehen.

Sam
quelle
2
Danke, genau das habe ich gebraucht. Ich würde zustimmen, dass es die beste Vorgehensweise ist, die Leitung einzuschließen, aber ein Webdienst, mit dem ich verbunden bin, erwartet dies nicht.
Jgrowl
6
Gut, dass es funktioniert, aber der FWIW-Dienst ist fehlerhaft, wenn er keine legale XML-Datei akzeptieren kann. Daher ist es wahrscheinlich gut, einen Fehlerbericht dagegen einzureichen.
StaxMan
4
Funktioniert nicht mit JAXB in JDK1.6. Die richtige Lösung finden Sie in der Antwort von so_mv.
sversch
1
Das explodiert im Flug: Ausnahme.
Nicolas Barbulesco
1
@sversch: Sie können Eigenschaftsklasse versuchen: "com.sun.xml.internal.bind.xmlHeaders"
baybora.oren
119

in JAXB ist das Teil von JDK1.6

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
so_mv
quelle
13
Dies ergibt nicht das erwartete Ergebnis. Dadurch wird die gesamte XML-Deklarationszeile entfernt. Ich möchte nur das standaloneAttribut in der XML-Deklaration entfernen .
Nicolas Barbulesco
Wenn Sie sich fragen, warum dies bei Ihnen nicht so funktioniert wie bei mir, lautet die Antwort, dass der Effekt davon abhängt, welche Marschall-API Sie verwenden. Für Marschall (Object, Outputstream) und Marschall (Object, Writer) funktioniert dies wie hier vorgeschlagen. Für Marschall (Objekt, Knoten) hat dies keine Auswirkung. Die verbleibenden Auswirkungen auf die Marschall-API finden Sie hier im Abschnitt Unterstützte Eigenschaften.
Lasse Samson
58

Sie können entweder verwenden

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

oder

marshaller.setProperty("com.sun.xml.bind.xmlDeclaration", false)

Um die Standard-XML-Deklaration zu deaktivieren und anschließend Ihre benutzerdefinierte XML-Deklaration hinzuzufügen,

<?xml version="1.0" encoding="UTF-8"?>

durch

marshaller.setProperty("com.sun.xml.bind.xmlHeaders",
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

auf die generierte XML, wodurch die eigenständige Eigenschaft "yes" vermieden wird .

WarFox
quelle
2
Die "setProperty" mit "xmlDeclaration" explodiert im Flug: Ausnahme.
Nicolas Barbulesco
2
Die Zeile "setProperty" mit "xmlHeaders" schlägt ebenfalls fehl. PropertyException. Das ist also keine Lösung.
Nicolas Barbulesco
Welche Version von Java und Jaxb verwenden Sie?
WarFox
@ WarFox Der Befehl setProperty with xmlHeaders funktioniert nicht mit jdk1.6.0_24 und JAXB Version 2.1
Bryan Larson
2
Unabhängig von Java6 oder Java7 musste ich 'intern' hinzufügen, dh marshaller.setProperty ("com.sun.xml.internal.bind.xmlHeaders", "<? Xml version =" 1.0 "encoding =" UTF-8 " "?>");
Caoilte
7

Nur wenn noch jemand mit diesem Problem zu kämpfen hat, können Sie die Verwendung in Betracht ziehen

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);

Um die gesamte XML-Deklaration zu entfernen, schreiben Sie einfach Ihre eigene Stringam Anfang Ihres Ausgabestreams / Ihrer Ausgabemethode

benez
quelle
5

Wenn Sie ein Dokument abhängig machen DOCTYPE(z. B. benannte Entitäten verwenden), standalone="yes"wird es nicht mehr eigenständig und ist daher in der XML-Deklaration nicht zulässig.

Standalone-XML kann jedoch überall verwendet werden, während Nicht-Standalone für XML-Parser, die keine externen Dateien laden, problematisch ist.

Ich sehe nicht ein, wie diese Deklaration ein Problem sein könnte, außer für die Interoperabilität mit Software, die XML nicht unterstützt, aber eine schreckliche Regex-Suppe.

Kornel
quelle
1
Genau, jedes angeblich XML-Verarbeitungssystem, das die XML-Deklaration blockiert, scheint höchst verdächtig.
StaxMan
1
Wie beantwortet es die Frage?
ᄀ ᄀ
Wie macht man das Dokument abhängig DOCTYPE?
Lii
3
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
jaxbMarshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");

Dies funktionierte bei mir mit JDK1.7. standalone = "no" kann entfernt werden, um nur den Rest des XML-Teils zu erhalten

Debasis Das
quelle
1
Fehler: javax.xml.bind.PropertyException: name: com.sun.xml.internal.bind.xmlHeaders Wert: <? xml version = "1.0" encoding = "UTF-8"?>
aswzen
3

Wenn Sie nur das Standardpaket javax.xml verwenden, können Sie die Option JAXB_FRAGMENT des Marshallers auf 'true' setzen (dies lässt die Standardanweisung für die XML-Verarbeitung weg) und die Methode writeProcessingInstruction des XMLStreamWriter verwenden, um Ihre eigenen einzufügen:

xmlStreamWriter.writeProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");
jaxbMarshaller.setProperty( Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
jaxbMarshaller.marshal(object, xmlStreamWriter);
xmlStreamWriter.writeEndDocument();
eddo
quelle
2

Sie können verwenden: marshaller.setProperty ("jaxb.fragment", Boolean.TRUE);

Es funktioniert für mich unter Java 8

William Funchal Pereira
quelle
1

Ich habe keinen ausreichend hohen "Ruf", um das "Privileg" zu haben, Kommentare abzugeben. ;-);

@Debasis, beachten Sie, dass die von Ihnen angegebene Eigenschaft:

"com.sun.xml.internal.bind.xmlHeaders"

sollte sein:

"com.sun.xml.bind.xmlHeaders" (without the "internal", which are not meant to be used by the public)

Wenn ich die "interne" Eigenschaft wie Sie verwende, erhalte ich eine javax.xml.bind.PropertyException

Ari
quelle
1

Wenn Sie eine Eigenschaftsausnahme erhalten, fügen Sie die folgende Konfiguration hinzu:

jaxbMarshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders",
              "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
jaxbMarshaller.setProperty("com.sun.xml.internal.bind.xmlDeclaration", Boolean.FALSE);
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);  
Alisha Setia
quelle
1

Ich verwende Java 1.8 und JAXB 2.3.1

Stellen Sie zunächst sicher, dass Sie Java 1.8 in pom.xml verwenden

<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>

Dann habe ich im Quellcode verwendet: (der Schlüssel war der interne Teil)

// remove standalone=yes
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
Cesar
quelle
0

Probier's einfach

private String marshaling2(Object object) throws JAXBException, XMLStreamException {
    JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
    jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
    StringWriter writer = new StringWriter();
    writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    jaxbMarshaller.marshal(object, writer);
    return writer.toString();
  }
Bernardo Mello
quelle
0

Wenn Sie haben <?xml version="1.0" encoding="UTF-8" standalone="yes"?>

aber will das: <?xml version="1.0" encoding="UTF-8"?>

Mach einfach:

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
In der Hälfte gebacken
quelle