我需要一种有效的方法将 XML 转换为Java 中有意义的域对象。下面是我必须使用的 XML 的选择(某些值已被遮盖)。以下是我必须处理的基本限制:
- 没有可使用的架构。由于变量“嵌套”,自动生成的模式效果不佳。
- 任何给定的域对象可以包含 0-* 域对象标签
- 任何给定的域对象都可以包含 0-* 值标签。
- 并非所有的嵌套都是一样的。在某些情况下,值的“键”包括隐式嵌套。例如,“config[0].cbs”表示配置对象的集合,每个对象都有不同的 .cbs 值
- 可能无法更改 XML 结构。
- “表示”属性指示类型。
- “nestedKey”属性表示类型内的变量名。
- 这些 XML 文件可能非常大。
我尝试过使用 JAXB,但由于标签的“通用性”,事情没有解决。也许我的 JAXB-fu 不够。当前的实现(我继承了这个)是 SAX,但它实际上不起作用。我看过 XStream,但它似乎对标签假设了一些语义结构。
我想要一种代码最少、最灵活、最可扩展的方法来生成有意义的域对象。如果可能的话,我想避免嵌套 HashMaps(这是当前解决方案的一部分,不起作用)。欢迎创造性的、hack-y 或聪明的想法以及直截了当的“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>
...