2009-06-20 17 views
17

Necesito construir un documento XML a partir de una jerarquía de objetos Java. Tanto las clases de Java como el formato XML son fijos. Así que no puedo usar un serializador XML como XStream: basa el formato XML en las clases de Java. Del mismo modo, una tecnología de enlace XML de Java como JAXB no funcionará, ya que crea clases de Java a partir del esquema XML [ed: pero ver a continuación]. Necesito un enfoque manual.¿Cómo construir un documento XML en Java de forma concisa?

La ruta de bajo perfil de StringBuilder da como resultado un código frágil y defectuoso (¡al menos para mí!).

Una API como JAXP o JDOM conduce a un código mucho más robusto, pero estos son bastante detallados.

Groovy tiene un elegante MarkupBuilder:

def writer = new StringWriter() 
def xml = new MarkupBuilder(writer) 
xml.records() { 
    car(name:'HSV Maloo', make:'Holden', year:2006) { 
    country('Australia') 
    record(type:'speed', 'Production Pickup Truck with speed of 271kph') 
    } 
    car(name:'P50', make:'Peel', year:1962) { 
    country('Isle of Man') 
    record(type:'size', 'Smallest Street-Legal Car at 99cm wide and 59 kg') 
    } 
} 

Otros idiomas (. Ej Ruby) tienen incluso mejores, aunque yo quiero estar con Java puro. Parece que hay algunos nuevos constructores XML para Java, como practicalxml y James Murty's xmlbuilder.

¿Cuáles son los enfoques más elegantes para construir documentos XML en Java?

Resumen:

Jon Doe sugirió dom4j y jdom.

CurtainDog recomendó utilizar JAXB de todos modos, y jherico me indicó que esta era una sugerencia pertinente: podría utilizar Dozer para mapear entre mis JavaBeans actuales y JAXB JavaBeans.

thaggie recomienda JIBX y está de acuerdo con CurtainDog y jherico en que las tecnologías de enlace son realmente prácticas.

StaxMan recomienda StaxMate.

De las cosas que he visto, practicalxml y el xmlbuilder de James Murty parecen ser los constructores más concisos, aunque son bastante nuevos. Las tecnologías de enlace como JAXB parecen ofrecer seguridad/automatización adicional. De las opciones principales, dom4j parece decente, aunque sigue siendo bastante detallado. Ofrece una "interfaz fluida" (mutators devuelven una referencia al objeto mutado de manera que se pueden encadenar juntos), que me gusta:

public Document createDocument() { 
    Document document = DocumentHelper.createDocument(); 
    Element root = document.addElement("root"); 
    Element author2 = root.addElement("author") 
     .addAttribute("name", "Toby") 
     .addAttribute("location", "Germany") 
     .addText("Tobias Rademacher"); 
    Element author1 = root.addElement("author") 
     .addAttribute("name", "James") 
     .addAttribute("location", "UK") 
     .addText("James Strachan"); 
    return document; 
} 

Para la concisión, se puede envolver una fachada fina sobre esta API para proporcionar terso sinónimos de algunos de estos métodos (p. ej., attr() en lugar de addAttribute()).

¡Gracias a todos!

P.S .: Stephan Schmidt trabajó en Java MarkupBuilder, aunque parece que no lo ha publicado.

+0

Corrija el enlace de dom4j a http://dom4j.sourceforge.net/ :) –

+0

@PawelVeselov - gracias, es triste cómo dom4j.org consiguió coopted. –

+0

(O/T) @JimFerrans No creo que haya sido cooptado, simplemente ya no mencionan el software dom4j. El estilo de la página entre ellos y la página de la biblioteca dom4j es demasiado similar para esos tipos que no tienen el mismo techo :) –

Respuesta

8

dom4j o jdom son probablemente las más elegantes, puede escribir el código que más le guste. Dom4j tiene constructores si recuerdo, y sí, el código es más detallado.

Element.addElement("x").setAttribute("x", "y").xxxxx; 
+0

Gracias, no había considerado dom4j. –

1

¿Por qué no sólo tiene que utilizar JAXB todos modos .. entonces el problema se convierte en un objeto muy simple objeto de asignación y a evitar por completo XML.

+0

Necesito escribir un objeto para mapeo XML donde el XML es un estándar fijo (ADI 1.1 de CableLabs) y las clases de Java también están preordenadas. –

+0

Utilice JAXB para asignar clases de Java al esquema y luego use Dozer para asignar las clases de JAXB a las clases de Java preordenadas. – Jherico

+0

@Jherico: Gracias, todavía no he visto a Dozer. De modo que podría tomar el esquema deseado y usar JAXB para crear un conjunto correspondiente de clases JavaBean a partir de ellos, luego establecer una asignación Dozer de los JavaBeans existentes a los JAXB JavaBeans. Suena como más código pero también más automatización. Veo lo que significa CurtainDog ahora. –

0

Puede considerar JIBX, puede definir un mapping de las clases de modelo de su dominio al esquema XML de destino.

Alternativamente, si eso no es posible, aunque sé que indica que ha descontado el uso de tecnologías vinculantes, le recomiendo que revise esa decisión, copiar de su modelo de dominio a un modelo generado lo hará más limpio, más fácil de mantener y menos propenso a errores del código de lo que está proponiendo, (que JIBX también puede hacer).

Probablemente debería agregar, en mi experiencia, hacer preguntas sobre JIBX aquí es infructuoso, pero su lista de correo es muy útil.

1

Aunque no es tan conciso como los constructores en lenguajes de scripting, StaxMate hace las cosas bastante simples; generalmente tan simple como los modelos arbóreos estructuralmente, pero también admite adiciones tipeadas (conversiones implícitas). Y lo hace todo directamente en una transmisión, lo que significa un uso de memoria muy bajo (y alta velocidad si eso importa).

Por lo que vale, también es compatible con el estilo fluido (a partir de 2.0.x), ya que a menudo tiene sentido. El principal beneficio sobre las soluciones de enlace de datos completo (y el modelo de árbol) es probablemente el bajo uso de memoria; se mantiene muy poco estado, toda la producción se envía al destino lo antes posible.

2

Eche un vistazo a XOM. Es rápido, simple, correcto y no es detallado.

Cuestiones relacionadas