自定义Java XMLBuilder与基于标准类

w41d8nur  于 2023-05-05  发布在  Java
关注(0)|答案(5)|浏览(166)

XML生成的最佳性能解决方案是什么?
我的目标是从代码构建一些简单的XML。我将实现简单的基于StringBuffer的XML生成器。另一方面,有几个库,如http://code.google.com/p/java-xmlbuilder/http://code.google.com/p/xmltool/,它们有很好的DSL,但我猜缺乏性能。
由于我的目标是建立足够简单的XMLBuilder与伟大的性能,我想我会建立自定义的解决方案。它将包括:

  • 用于XML构造的基于Java的DSL(基本上是添加标记)
  • 基于StringBuffer的出色性能。
  • 添加XML标记时的字符串数据转义处理。
  • 自动缩进

如果我对性能的期望是错误的,请建议我使用现成的库。

**UPDATE.**为什么我认为标准的XML构建器的性能不是很好。

标准的XML生成器使用文档生成器工厂并在后台使用类。此外,这些类优化,以适应所有用户。例如我不需要命名空间支持等等。

<?xml version="1.0" encoding="utf-8">
<root>
 <testdata>value</testdata>
</root>
</xml>

考虑上面非常简单的XML代码。如果您使用标准工具构建,那么仅仅是创建一个简单的XML就需要做很多工作。我认为最好是自己用String生成它。

更新2。性能要求是代码应该尽可能多地执行生成简单XML所需的操作,而不是更多。
更新3.感谢每个人的伟大评论!现在我更好地理解了我需要什么,我最初的目标并没有用“性能”这个词非常正确地设定。我的真正目标是使用足够简单的解决方案和方便的DSL来描述XML结构并生成XML输出。

我将使用普通的Java对象作为XML的DSL,并使用XStream库生成XML,这是一个非常简单的解决方案。

**UPDATE 4. JAXB.**我讨论了XStream与JAXB的比较,发现JAXB比XStream快。另外,我已经在我的项目中使用了JAXB,我喜欢它的标准注解。我现在改变了主意,将选择JAXB,因为XStream最初是在JAXB不像今天这么好的时候大量开发的。

wlwcrazw

wlwcrazw1#

我会提出一些非常有争议的东西,但仍然...

使用两个库进行性能分析和性能测试

如果你没有时间,在我看来,假设某个东西很慢是错误的选择。因为如果事实证明它实际上并不慢,那么使用已经构建和支持的库/框架将保存大量时间。
另一个想法。无论如何,您都需要对已完成的高性能解决方案进行测试,以检查它是否真的具有高性能。因此,我强烈建议您在开始使用自己的库之前,先衡量一下可用库的性能。

f87krz0w

f87krz0w2#

关于:
标准的XML生成器使用文档生成器工厂并在后台使用类。此外,这些类优化,以适应所有用户。例如我不需要命名空间支持等等。
DOM的一个替代方案是StAX(JSR-173)。它是一个非常快的XML流API。有几个实现,我发现Woodstox是相当性能。

hs1rzwqc

hs1rzwqc3#

有强大而灵活的Groovy的NodeBuilder(http://groovy.codehaus.org/GroovyMarkup)。

def root = new NodeBuilder()
  .people(kind:'folks', groovy:true) {
    person(x:123,  name:'James', cheese:'edam') {
      project(name:'groovy')
      project(name:'geronimo')
    }
    person(x:234,  name:'bob', cheese:'cheddar') {
      project(name:'groovy')
      project(name:'drools')
    }
  }
XmlUtil.serialize(root, System.out)

这将生成一个XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<people kind="folks" groovy="true">
  <person x="123" name="James" cheese="edam">
    <project name="groovy"/>
    <project name="geronimo"/>
  </person>
  <person x="234" name="bob" cheese="cheddar">
    <project name="groovy"/>
    <project name="drools"/>
  </person>
</people>
brjng4g3

brjng4g34#

还有一个高性能的建议:使用StaxMate--它与基于Stax的底层XML编写器一样快,后者相当快(每秒40 - 80兆字节,持续)。只要确保你不使用默认的JDK 6 Stax实现(Sun sjsxp),而是使用更快的东西,比如Woodstox或Aalto。
我强烈建议不要编写自己的XML编写器;正如其他人所提到的,它通常是有风险的(很有可能你会忘记一些逃脱的部分),而且并不是所有的都可能比现有的有效的解决方案更快(不是所有现有的解决方案都是有效的;你需要找到那些)。最后...除非你真的想写这些东西,为什么不写一些更有趣和更有意义的东西呢?
但是如果你想做一些超越现有编写器的事情,你可以考虑使用一个简单的编写器,并用你需要的额外功能来增强它。例如,如果您只是使用StaxXMLStreamWriter作为基础,那么添加简单但有效的抽象是非常容易的。或者,如果你喜欢现有的包,看看你是否可以建议改进他们的作者(甚至代码贡献)。

lsmepo6l

lsmepo6l5#

强大的XmlBuilder

var xmlBuilder =
    XmlBuilder.create("people")
        .a("kind", "folks")
        .a("groovy", "true")
        .e("person")
        .a("x", "123")
        .a("name", "James")
        .a("cheese", "edam")
        .e("project")
        .a("name", "groovy")
        .a("self-closing", "true")
        .up()
        .e("project")
        .a("name", "geronimo")
        .a("self-closing", "true")
        .up()
        .up()
        .e("person")
        .a("x", "234")
        .a("name", "bob")
        .a("cheese", "cheddar")
        .e("project")
        .a("name", "groovy")
        .a("self-closing", "true")
        .up()
        .e("project")
        .a("name", "drools")
        .a("self-closing", "true");
System.out.println(xmlBuilder.toXml(Xml.XmlStringBuilder.Step.FOUR_SPACES));

这将生成一个XML文档:

<?xml version="1.0" encoding="UTF-8"?>
<people kind="folks" groovy="true">
    <person x="123" name="James" cheese="edam">
        <project name="groovy"/>
        <project name="geronimo"/>
    </person>
    <person x="234" name="bob" cheese="cheddar">
        <project name="groovy"/>
        <project name="drools"/>
    </person>
</people>

相关问题