具有嵌套通用标记的Java XML绑定

时间:2012-09-21 17:18:33

标签: java xml binding

我需要一种有效的方法将XML转换为Java中的有意义的域对象。下面是我必须使用的XML选择(某些值已被遮盖)。以下是我必须处理的基本限制:

  1. 没有架构可供使用。由于变量“嵌套”,自动生成的模式效果不佳。
  2. 任何给定的域对象都可以包含0- * domain-object标签
  3. 任何给定的域对象都可以包含0- *值标记。
  4. 并非所有嵌套都是相同的。在某些情况下,值的“键”包括隐式嵌套。例如,“config [0] .cbs”表示配置对象的集合,每个配置对象的值都不同.cbs
  5. 可能无法更改XML结构。
  6. “表示”属性表示类型。
  7. “nestedKey”属性表示类型中的变量名称。
  8. 这些XML文件可能非常大。
  9. 我已经尝试过使用JAXB,但由于标签的“通用性”,事情并没有成功。也许我的JAXB-fu不够用。当前的实现(我继承了这个)是SAX,但它实际上并不起作用。我看过XStream,但似乎假设标签有一些语义结构。

    我想要一种最少代码,最灵活,最可扩展的方法来生成有意义的域对象。如果可能的话,我想避免嵌套HashMaps(这是当前解决方案不起作用的一部分)。欢迎创意,黑客或聪明的想法,以及严格的“duh”答案。

    XML代码段:

    <?xml version="1.0"?>
    <domain-objects>
        <types language="C++">
            <type prefix="bool" language-representation="bool" />
            <type prefix="char" language-representation="char" />
            <type prefix="domain_object" language-representation="opti::DomainObject" />
            <type prefix="domain_object" language-representation="DomainObject" />
            <type prefix="double" language-representation="double" />
            <type prefix="float" language-representation="float" />
    ...
        </types>
        <domain-object key="(unique object id)" represents="PerfSuite">
            <domain-object key="(unique object id)" nestedKey="testCore" represents="PerfTestCore">
                <value key="suiteUuid" type="stl_string">(unique object id)</value>
                <value key="suiteName" type="stl_string">(some name)</value>
                <value key="suiteId" type="int">(some number)</value>
                <value key="suiteDeleted" type="bool">false</value>
            </domain-object>
            <domain-object key="(unique object id)" nestedKey="testResults" represents="PerfTestResults">
                <domain-object key="(unique object id)" nestedKey="services_0" represents="PerfServiceResult">
                    <domain-object key="(unique object id)" nestedKey="stepResults_0" represents="PerfStepResult">
                        <value key="ir.max" type="int64">(some number)</value>
                        <value key="ftd.avg" type="float">(some number)</value>
                        <value key="ftd.max" type="float">(some number)</value>
    ...
                    </domain-object>
                    <value key="duration" type="uint">(some number)</value>
                    <value key="flow" type="uint16">(some number)</value>
    ...
                            <value key="config[1].flrThreshold" type="float">(some number)</value>
                            <value key="config[1].fdvPercent" type="float">(some number)</value>
                            <value key="index" type="uint16">(some number)</value>
                            <value key="config[0].cbs" type="uint64">(some number)</value>
                            <value key="svlanVid" type="uint16">(some number)</value>
                            <value key="config[1].availThreshold" type="float">(some number)</value>
    ...
    

1 个答案:

答案 0 :(得分:0)

没有一个工具可以完全解决这个问题。

JAXB可能仍然是解析部分的正确答案。如果您希望将每个域对象都转换为您的实际域对象,则必须自己完成最终传递。

JAXB无法解析“float”以确定它需要查找types表以查找float映射到float。在对象中查找“config [1] .fdvPercent”也超出了它的能力。

从我所看到的,您有一个可以由架构描述的相当一致的文档结构。在XML模式中编写它,或者注释类应该很简单。

domain-objects = types+, domain-object+
domain-object = domain-object*, value*

从这里开始,你的工作已经完成了。我怀疑你需要做很多事情:

  • 对每个元素中的字符串进行每类型解析,以便您可以获取每个
  • 的值
  • 从类型的字符串值到每类型解析器的映射(看起来您可能需要额外的映射步骤,以便从您使用的C ++类型转换为Java类型)
  • 值键的解析器,以便您可以找到要将值应用于
  • 的变量
  • 实例化对象并在创建的对象中设置值的一些反射

我无法猜测nestedKey或代表什么意味着你。这可能需要额外的步骤。