改进 xsd:any 在 Java 代码中的使用
Improve usage of xsd:any in Java code
我有一些遗留 XML 文档要导入到我的一个软件中。目前给我带来一些麻烦的部分是 Param 元素的内容:
Sample.xml
<...>
<Param>
<IdNumber>12345678</IdNumber>
<Factor>12.3</Factor>
<Date>2015-07-01</Date>
<Counter unit="1">
<Medium>1</Medium>
...
</Counter>
<Counter unit="2">
<Medium>4</Medium>
...
</Counter>
...
</Param>
</...>
Param 中可以有很多(数量可以变化)子元素,为了避免在 XSD 中列出所有子元素,声明如下:
Schema.xsd
...
<xs:element name="Param">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip" />
</xs:sequence>
</xs:complexType>
</xs:element>
...
当我使用 XJC 工具为 marshalling/unmarshalling 生成一对一的 classes 时,我得到的是:
Param.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"any"
})
@XmlRootElement(name = "Param")
public class Param {
@XmlAnyElement
protected List<Element> any;
public List<Element> getAny() {
if (any == null) {
any = new ArrayList<Element>();
}
return this.any;
}
}
我的问题是使用 Param
class 并不容易,因为它只包含 Element 的列表,需要改进它。
我看到 3 个解决方案:
- 什么都不改变
- 通过声明所有可能的元素(和子元素)来完成 XSD,允许我在
Param
class.[=49= 中对每个元素进行特定访问]
- 在
Param
中使用 Map 而不是列表来简化 searching/extracting 元素。虽然我不知道如何实现这一点,但 <Counter unit="1">
和 <Counter unit="2">
的情况可能会有问题。
因此,我正在寻找一些建议,以选择这三种解决方案中的一种 或 提出另一种解决方案。
我的看法;
- 我想说的是,如果您知道 100% 确定会发生什么,那么选项 2 就是您的选择。然而,为 XSD 建模可能会很痛苦。
- 选项3对我来说似乎不可行,深度> 2的反例就是一个例子。
- 最后,我在采用选项 1 的项目中工作过,也应该考虑它(您需要编写和维护代码,但让它工作非常简单)。
我有一些遗留 XML 文档要导入到我的一个软件中。目前给我带来一些麻烦的部分是 Param 元素的内容:
Sample.xml
<...>
<Param>
<IdNumber>12345678</IdNumber>
<Factor>12.3</Factor>
<Date>2015-07-01</Date>
<Counter unit="1">
<Medium>1</Medium>
...
</Counter>
<Counter unit="2">
<Medium>4</Medium>
...
</Counter>
...
</Param>
</...>
Param 中可以有很多(数量可以变化)子元素,为了避免在 XSD 中列出所有子元素,声明如下:
Schema.xsd
...
<xs:element name="Param">
<xs:complexType>
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip" />
</xs:sequence>
</xs:complexType>
</xs:element>
...
当我使用 XJC 工具为 marshalling/unmarshalling 生成一对一的 classes 时,我得到的是:
Param.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"any"
})
@XmlRootElement(name = "Param")
public class Param {
@XmlAnyElement
protected List<Element> any;
public List<Element> getAny() {
if (any == null) {
any = new ArrayList<Element>();
}
return this.any;
}
}
我的问题是使用 Param
class 并不容易,因为它只包含 Element 的列表,需要改进它。
我看到 3 个解决方案:
- 什么都不改变
- 通过声明所有可能的元素(和子元素)来完成 XSD,允许我在
Param
class.[=49= 中对每个元素进行特定访问] - 在
Param
中使用 Map 而不是列表来简化 searching/extracting 元素。虽然我不知道如何实现这一点,但<Counter unit="1">
和<Counter unit="2">
的情况可能会有问题。
因此,我正在寻找一些建议,以选择这三种解决方案中的一种 或 提出另一种解决方案。
我的看法;
- 我想说的是,如果您知道 100% 确定会发生什么,那么选项 2 就是您的选择。然而,为 XSD 建模可能会很痛苦。
- 选项3对我来说似乎不可行,深度> 2的反例就是一个例子。
- 最后,我在采用选项 1 的项目中工作过,也应该考虑它(您需要编写和维护代码,但让它工作非常简单)。