如何用 Java 简洁地构建 XML 文档?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1020828/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to build an XML document in Java concisely?
提问by Jim Ferrans
I need to build an XML document from a Java object hierarchy. Both the Java classes and the XML format are fixed. So I can't use an XML serializer like XStream: it bases the XML format on the Java classes. Likewise, a Java XML binding technology like JAXBwon't work, since it creates Java classes from the XML schema [ed: but see below]. I need a manual approach.
我需要从 Java 对象层次结构构建一个 XML 文档。Java 类和 XML 格式都是固定的。所以我不能使用像XStream这样的 XML 序列化器:它基于 Java 类的 XML 格式。同样,像JAXB这样的 Java XML 绑定技术也不起作用,因为它从 XML 模式创建 Java 类 [ed: 但见下文]。我需要手动方法。
The low-tech StringBuilder route results in fragile and buggy code (at least for me!).
低技术的 StringBuilder 路线导致代码脆弱且有缺陷(至少对我而言!)。
An API like JAXPor JDOMleads to much more robust code, but these are pretty verbose.
像JAXP或JDOM这样的 API会产生更健壮的代码,但这些代码非常冗长。
Groovyhas an elegant MarkupBuilder:
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')
}
}
Other languages (eg. Ruby) have even better ones, though I want to stay with pure Java. There do seem to be some new XML builders for Java, such as practicalxmland James Murty's xmlbuilder.
其他语言(例如Ruby)有更好的语言,但我想继续使用纯 Java。这里似乎是对Java的一些新的XML建设者,如practicalxml和詹姆斯·穆尔蒂的xmlbuilder。
What are the more elegant approaches for building XML documents in Java?
在 Java 中构建 XML 文档的更优雅的方法是什么?
Summary:
概括:
Jon Doe suggested dom4jand jdom.
CurtainDog recommended using JAXB anyway, and jherico clued me in that this was a pertinant suggestion: you could then use Dozer to map between my current JavaBeans and the JAXB JavaBeans.
CurtainDog 无论如何都推荐使用 JAXB,而 jherico 告诉我这是一个相关的建议:然后您可以使用 Dozer 在我当前的 JavaBeans 和 JAXB JavaBeans 之间进行映射。
thaggie recommends JIBXand agreed with CurtainDog and jherico that binding technologies are actually practical.
thaggie 推荐JIBX并同意 CurtainDog 和 jherico 的绑定技术实际上是实用的。
StaxMan recommends StaxMate.
StaxMan 推荐StaxMate。
Of the stuff I've looked at, practicalxml and James Murty's xmlbuilder seem to be the most concise builders, though are rather newish. The binding technologies like JAXB seem to offer extra safety/automation. Of the mainstream choices, dom4jseems decent, though still kind of verbose. It offers a "fluent interface" (mutators return a reference to the mutated object so they can be chained together), which I like:
在我看过的东西中,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;
}
For conciseness, you could wrap a thin facade over this API to provide terse synonyms for some of these methods (eg, attr() instead of addAttribute()).
为简洁起见,您可以在此 API 上包装一个薄的外观,为其中一些方法提供简洁的同义词(例如,attr() 而不是 addAttribute())。
Thanks all!
谢谢大家!
P.S.: Stephan Schmidt worked on a Java MarkupBuilder, though seems not to have published it.
PS:Stephan Schmidt 在 Java MarkupBuilder 上工作,但似乎没有发布它。
采纳答案by Jim Ferrans
dom4j or jdom are probably the most elegant, you can write code how you like it. Dom4j has builders if I recall, and yes the code is more verbose.
dom4j 或 jdom 可能是最优雅的,您可以随心所欲地编写代码。如果我记得的话,Dom4j 有构建器,是的,代码更冗长。
Element.addElement("x").setAttribute("x", "y").xxxxx;
回答by StaxMan
While not quite as concise as builders in scripting languages, StaxMatemakes things quite simple; generally as simple as tree models structurally, but it additionally supports typed addition (implicit conversions). And does this all directly into a stream, meaning very low memory usage (and high speed if that matters).
虽然不像脚本语言中的构建器那么简洁,但StaxMate使事情变得非常简单;通常在结构上与树模型一样简单,但它还支持类型化加法(隐式转换)。并且将这一切直接放入流中,这意味着内存使用量非常低(如果重要的话,速度也会很高)。
For what it's worth, it also supports fluent style (as of 2.0.x), since it does often make sense. The main benefit over full data binding (and tree model) solutions is probably low memory usage; very little state is kept around, all output goes out to destination as soon as possible.
就其价值而言,它还支持流畅的样式(从 2.0.x 开始),因为它通常是有意义的。完整数据绑定(和树模型)解决方案的主要好处可能是内存使用率低;保留很少的状态,所有输出都会尽快到达目的地。
回答by CurtainDog
Why don't you just use JAXB anyway.. then the problem becomes a very simple object to object mapping and you avoid xml altogether.
你为什么不直接使用 JAXB .. 那么问题就变成了一个非常简单的对象到对象映射,你完全避免使用 xml。
回答by Tom
You may be able to consider JIBX, you may be able to define a mappingfrom your domain model classes to your target XML schema.
您可以考虑JIBX,您可以定义从域模型类到目标 XML 模式的映射。
Alternatively, if that's not possible, although I know you state that you've discounted using binding technologies I'd encourage you to review that decision, copying from your domain model into a generated model will most likely make for cleaner, more maintainable and less error prone code than what you're proposing, (which JIBX can also do).
或者,如果这是不可能的,虽然我知道你说你已经使用绑定技术打折了,但我鼓励你检查这个决定,从你的域模型复制到生成的模型很可能会更干净、更易于维护和更少容易出错的代码比您提议的要多(JIBX 也可以这样做)。
I should probably add, in my experience asking questions about JIBX here is fruitless but their mailing list is very helpful.
我应该补充一点,根据我的经验,在这里询问有关 JIBX 的问题是徒劳的,但他们的邮件列表非常有帮助。

