如何简洁地在Java中构建XML文档?

时间:2009-06-20 03:02:20

标签: java xml builder

我需要从Java对象层次结构构建XML文档。 Java类和XML格式都是固定的。所以我不能使用像XStream这样的XML序列化器:它基于Java类的XML格式。同样,像JAXB这样的Java XML绑定技术也不起作用,因为它从XML模式创建Java类[编辑:但见下文]。我需要手动方法。

低技术的StringBuilder路由导致脆弱和错误的代码(至少对我而言!)。

JAXPJDOM这样的API会带来更强大的代码,但这些代码非常冗长。

Groovy有一个优雅的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')
  }
}

其他语言(例如Ruby)甚至有更好的语言,但我想继续使用纯Java。似乎有一些新的Java构建器用于Java,例如practicalxml和James Murty的xmlbuilder

用Java构建XML文档有哪些更优雅的方法?

要点:

Jon Doe建议dom4jjdom

无论如何,CurtainDog推荐使用JAXB,jherico告诉我这是一个非常重要的建议:然后你可以使用Dozer在我当前的JavaBeans和JAXB JavaBeans之间进行映射。

thaggie建议JIBX并同意CurtainDog和jherico的说法,绑定技术实际上是实用的。

StaxMan建议StaxMate

在我看过的内容中,Practicalxml和James Murty的xmlbuilder似乎是最简洁的构建者,虽然相当新鲜。像JAXB这样的绑定技术似乎提供了额外的安全/自动化。在主流选择中,dom4j似乎不错,但仍然有点冗长。它提供了一个“流畅的界面”(mutators返回对变异对象的引用,因此它们可以链接在一起),我喜欢:

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;
}

为了简洁起见,您可以在此API上包含一个薄外观,以便为其中一些方法提供简洁的同义词(例如,attr()而不是addAttribute())。

全部谢谢!

P.S。:Stephan Schmidt参与了Java MarkupBuilder,虽然似乎没有发表它。

6 个答案:

答案 0 :(得分:10)

dom4j或jdom可能是最优雅的,你可以根据自己的喜好编写代码。如果我记得,Dom4j有建设者,是的,代码更详细。

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

答案 1 :(得分:2)

看看XOM。它快速,简单,正确,并且不冗长。

答案 2 :(得分:1)

为什么不使用JAXB呢?那么问题就变成了一个非常简单的对象映射对象,你完全避免使用xml。

答案 3 :(得分:1)

虽然不像脚本语言中的构建器那么简洁,StaxMate使事情变得非常简单;通常在结构上与树模型一样简单,但它还支持类型加法(隐式转换)。这一切都直接进入流中,这意味着内存使用率非常低(如果重要的话,速度很快)。

对于它的价值,它也支持流畅的风格(从2.0.x开始),因为它确实有意义。完整数据绑定(和树模型)解决方案的主要好处可能是内存使用率低;保持很少的状态,所有输出都尽快到达目的地。

答案 4 :(得分:1)

Underscore-java 有一个从对象创建 xml 字符串的构建器。

    String xml = U.objectBuilder().add("author", U.arrayBuilder()
            .add(U.objectBuilder()
                .add("-name", "Toby")
                .add("-location", "Germany")
                .add("#text", "Tobias Rademacher"))
            .add(U.objectBuilder()
                .add("-name", "James")
                .add("-location", "UK")
                .add("#text", "James Strachan"))).toXml();

// <?xml version="1.0" encoding="UTF-8"?>
// <root>
//   <author name="Toby" location="Germany">Tobias Rademacher</author>
//   <author name="James" location="UK">James Strachan</author>
// </root>

答案 5 :(得分:0)

您可以考虑JIBX,您可以将域模型类中的mapping定义为目标XML架构。

或者,如果那是不可能的,虽然我知道你声明你使用绑定技术打折我鼓励你复习这个决定,从你的领域模型复制到生成的模型很可能会更清洁,更多可维护且不易出错的代码比您提出的代码(JIBX也可以这样做)。

我应该补充一点,根据我的经验,在这里询问有关JIBX的问题是徒劳的,但他们的邮件列表非常有帮助。