21

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

技术含量低的 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 的新 XML 构建器,例如actualxml和 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看起来不错,但仍然有点冗长。它提供了一个“流利的接口”(突变器返回对突变对象的引用,因此它们可以链接在一起),我喜欢它:

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())。

谢谢大家!

PS:Stephan Schmidt 从事 Java MarkupBuilder工作,但似乎没有发布它。

4

6 回答 6

10

dom4j 或 jdom 可能是最优雅的,您可以按照自己的喜好编写代码。如果我记得的话,Dom4j 有构建器,是的,代码更冗长。

Element.addElement("x").setAttribute("x", "y").xxxxx;
于 2009-06-20T03:10:58.660 回答
2

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

于 2009-07-15T11:40:48.733 回答
1

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

于 2009-06-20T03:19:18.207 回答
1

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

值得一提的是,它还支持流畅的样式(从 2.0.x 开始),因为它通常是有意义的。与完整数据绑定(和树模型)解决方案相比,主要优势可能是内存使用率低;很少有状态被保留,所有输出都会尽快到达目的地。

于 2009-06-20T06:08:41.523 回答
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>
于 2021-02-22T07:39:58.520 回答
0

您可以考虑JIBX,您可以定义从域模型类到目标 XML 模式的映射。

或者,如果这是不可能的,虽然我知道你说你已经打折使用绑定技术我鼓励你审查这个决定,从你的域模型复制到生成的模型很可能会使更清洁、更可维护和更少比您建议的更容易出错的代码(JIBX 也可以这样做)。

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

于 2009-06-20T05:27:10.707 回答