36.3. 使用 Unbound 属性
概述
XML 架构有一个机制,允许您在复杂类型定义中保留任意属性的拥有者。通过使用这种机制,您可以定义可以具有任何属性的复杂类型。例如,您可以创建一个类型来定义元素 <robot name="epsilon" />、<robot age="10000" /> 或 <robot type="weevil" /> 而不指定三个属性。这在您的数据中的灵活性需要时特别有用。
在 XML 架构中定义
Undeclared 属性在 XML 架构中使用 anyAttribute
元素定义。它可用于在可以使用属性元素的位置。anyAttribute
元素没有属性,如 例 36.7 “带有 Undeclared Attribute 的复杂类型” 所示。
例 36.7. 带有 Undeclared Attribute 的复杂类型
<complexType name="arbitter">
<sequence>
<element name="name" type="xsd:string" />
<element name="rate" type="xsd:float" />
</sequence>
<anyAttribute />
</complexType>
定义的类型 arbitter
具有两个元素,并可具有任何类型的一个属性。例 36.8 “使用通配符属性定义的元素示例” 中显示的元素有三个元素,它们都可以从复杂的类型 arbitter
生成。
例 36.8. 使用通配符属性定义的元素示例
<officer rank="12"><name>...</name><rate>...</rate></officer> <lawyer type="divorce"><name>...</name><rate>...</rate></lawyer> <judge><name>...</name><rate>...</rate></judge>
映射到 Java
当包含 任何Attribute
元素的复杂类型映射到 Java 时,代码生成器会将名为 otherAttributes
的成员添加到生成的类。otherAttributes
是 java.util.Map<QName, String
>,它是一种 getter 方法,它返回了映射的实时实例。由于 getter 返回的映射是实时的,对映射的任何修改都会被自动应用。例 36.9 “带有 Undeclared Attribute 的复杂类型” 显示为 例 36.7 “带有 Undeclared Attribute 的复杂类型” 中定义的复杂类型生成的类。
例 36.9. 带有 Undeclared Attribute 的复杂类型
public class Arbitter { @XmlElement(required = true) protected String name; protected float rate; @XmlAnyAttribute private Map<QName, String> otherAttributes = new HashMap<QName, String>(); public String getName() { return name; } public void setName(String value) { this.name = value; } public float getRate() { return rate; } public void setRate(float value) { this.rate = value; } public Map<QName, String> getOtherAttributes() { return otherAttributes; } }
使用未压缩属性
生成的类 的另一个Attributes
成员应该被填充到 Map
对象。该映射使用 QNames
键。获取映射后,您可以访问对象上设置的任何属性,并在对象上设置新属性。
例 36.10 “使用 Undeclared Attributes” 显示使用未压缩属性的代码示例。
例 36.10. 使用 Undeclared Attributes
Arbitter judge = new Arbitter(); Map<QName, String> otherAtts = judge.getOtherAttributes(); QName at1 = new QName("test.apache.org", "house"); QName at2 = new QName("test.apache.org", "veteran"); otherAtts.put(at1, "Cape"); otherAtts.put(at2, "false"); String vetStatus = otherAtts.get(at2);
例 36.10 “使用 Undeclared Attributes” 中的代码执行以下操作:
获取含有未压缩属性的 map。
创建 QName 以用于属性。
将属性的值设置为映射。
检索其中一个属性的值。