Eliminar 'standalone = "yes"' del XML generado

82

¿Conoce una configuración JAXB para evitar que se genere standalone = "yes" en el XML resultante?

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
Johan Pelgrim
fuente
7
¿Por que eso es un problema?
Kornel
@Kornel en mi proyecto que para acostumbrarse con Tibco y WebMethod, generará un error porque standalone = yes no se reconoce
aswzen

Respuestas:

62

Esta propiedad:

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

... se puede utilizar para no tener:

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

Sin embargo, no consideraría esta mejor práctica.

Sam
fuente
2
Gracias, esto es exactamente lo que necesitaba. Estoy de acuerdo en que es una buena práctica incluir la línea, pero un servicio web con el que estoy interactuando no lo espera.
jgrowl
6
Es bueno que funcione, pero FWIW, el servicio está roto si no puede aceptar xml legal, por lo que probablemente sea bueno presentar un informe de error en su contra.
StaxMan
4
No funciona con JAXB en JDK1.6. Vea la respuesta de so_mv para la solución correcta.
sversch
1
Que explota en vuelo: excepción.
Nicolas Barbulesco
1
@sversch: puede probar la clase de propiedad: "com.sun.xml.internal.bind.xmlHeaders"
baybora.oren
120

en JAXB que es parte de JDK1.6

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
so_mv
fuente
13
Esto no da el resultado esperado. Esto elimina toda la línea de declaración XML. Lo que quiero es simplemente eliminar el standaloneatributo en la declaración XML.
Nicolas Barbulesco
Si se pregunta por qué esto no funciona para usted, como lo hice yo, entonces la respuesta es que el efecto depende de qué api marshal esté utilizando. Para marshal (Object, Outputstream) y marshal (Object, Writer), esto funciona como se sugiere aquí. Para mariscal (Objeto, Nodo) no tiene ningún efecto. Para las implicaciones restantes de la API de marshal, eche un vistazo aquí en la sección Propiedades admitidas.
Lasse Samson
59

Puedes usar

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

o

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

para deshabilitar la declaración XML predeterminada y luego agregar su declaración XML personalizada,

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

por

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

al xml generado, evitando así la propiedad standalone = "yes" .

WarFox
fuente
2
El "setProperty" con "xmlDeclaration" explota en vuelo: excepción.
Nicolas Barbulesco
2
La línea "setProperty" con "xmlHeaders" también falla. PropertyException. Entonces esta no es una solución.
Nicolas Barbulesco
¿Qué versión de java y jaxb estás usando?
WarFox
@WarFox El comando setProperty con xmlHeaders no funciona con jdk1.6.0_24 y JAXB versión 2.1
Bryan Larson
3
Independientemente de java6 o java7, tuve que agregar 'interno', es decir, marshaller.setProperty ("com.sun.xml.internal.bind.xmlHeaders", "<? Xml version = \" 1.0 \ "encoding = \" UTF-8 \ "?>");
Caoilte
7

solo si alguien más todavía está luchando con este problema, puede considerar usar

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

para eliminar toda la declaración XML y simplemente escriba la suya propia Stringal comienzo de su flujo / método de salida

benez
fuente
5

Si hace que el documento dependa de DOCTYPE(por ejemplo, utiliza entidades con nombre), dejará de ser independiente, por standalone="yes"lo que no se permitirá en la declaración XML.

Sin embargo, el XML independiente se puede usar en cualquier lugar, mientras que el no independiente es problemático para los analizadores XML que no cargan externos.

No veo cómo esta declaración podría ser un problema, aparte de la interoperabilidad con software que no es compatible con XML, pero con una horrible sopa de expresiones regulares.

Kornel
fuente
1
Exactamente, cualquier sistema de procesamiento xml que supuestamente emite una declaración xml parece muy sospechoso.
StaxMan
1
¿De qué manera responde a la pregunta?
ᄂ ᄀ
¿Cómo se hace depender el documento 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\"?>");

Esto funcionó para mí con JDK1.7. standalone = \ "no \" se puede eliminar para obtener solo el resto de la parte xml

Debasis Das
fuente
1
error: javax.xml.bind.PropertyException: nombre: com.sun.xml.internal.bind.xmlHeaders valor: <? xml version = "1.0" encoding = "UTF-8"?>
aswzen
3

Si está utilizando solo el paquete javax.xml predeterminado, puede establecer la opción JAXB_FRAGMENT del marshaller en 'true' (esto omite la instrucción de procesamiento xml predeterminada) y usar el método writeProcessingInstruction de XMLStreamWriter para insertar el suyo:

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

Puede utilizar: marshaller.setProperty ("jaxb.fragment", Boolean.TRUE);

Me funciona en Java 8

William Funchal Pereira
fuente
1

No tengo una "reputación" lo suficientemente alta como para tener el "privilegio" de comentar. ;-)

@Debasis, tenga en cuenta que la propiedad que ha especificado:

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

debiera ser:

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

Si uso la propiedad "interna" como lo hizo, obtengo una javax.xml.bind.PropertyException

Ari
fuente
1

En caso de que obtenga una excepción de propiedad, agregue la siguiente configuración:

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
fuente
1

Estoy usando Java 1.8 y JAXB 2.3.1

Primero, asegúrese de usar java 1.8 en pom.xml

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

Luego, en el código fuente usé: (la clave era la parte interna)

// 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
fuente
0

sólo inténtalo

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
fuente
0

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

pero quiero esto: <?xml version="1.0" encoding="UTF-8"?>

Solo haz:

marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
Al horno en la mitad
fuente