JiBX 1.2,第2部分: 从XML模式到Java代码(二)2012-01-14 IBM Dennis Sosnoski为 TimeCard 生成的代码hrxml 目录中的 Ant build.xml 文件将定义尝试为 TimeCard 模式生成基本代码的 Ant 目标,包括默认生成和几个自定义示例(稍后讨论)。样例目录还包含一个测试程序 org.jibx.hrxml.Test。它将使用生成的数据模型类将样例文档解组,然后将文档重新编组并将结果与原始文档相比较。并且样例目录中有一组来自 HR-XML 发行版的测试文档。codegen 目标将使用默认值运行 CodeGen,compile 将编译生成的代码和测试代码,bind 将编译 JiBX 绑定,而 roundtrip 将对样例文档运行测试程序。您还可以使用 full 任务按顺序运行所有这些步骤。大多数通过模式生成代码的方式都将为每个 complexType 定义及枚举 simpleType 生成一个单独的类。通过在可能的位置检查引用和内联定义,并且忽略包括和导入的模式定义中未使用的定义,CodeGen 通常能够减少生成的类的数量。在 TimeCard 模式中,有总计 10 个全局(命名的)complexType 和附加的 23 个本地(匿名)complexType,以及 8 个枚举 simpleType。生成的默认数据模型将包含 15 个顶级类和 23 个内部类,要比根据模式组件计算的少一些。您稍后将看到,如果不需要用到全部模式组件,如何使用自定义进一步简化数据模型。<xs:choice> 处理清单 8 显示了 CodeGen 如何处理 TimeCardType complexType 定义中的两个元素之间的选择。默认情况下,CodeGen 将使用一个选择变量来跟踪目前处于活动状态的选择。选择中包括的值的 set 方法将允许您写入目前选择的新值,但是不能直接更改选择(如果您尝试这样做,则抛出 IllegalStateException)。要在设定后更改目前的选择,首先需要调用一个清除方法(此处为 clearReportedResourceSelect()),该方法将重置选择状态。清单 8. HR-XML TimeCard 生成的代码样例
/** * Schema fragment(s) for this class: * <pre> * <xs:complexType xmlns:ns="http://ns.hr-xml.org/2007-04-15" * xmlns:ns1="http://www.w3.org/XML/1998/namespace" * xmlns:xs="http://www.w3.org/2001/XMLSchema" name="TimeCardType"> * <xs:sequence> * <xs:element type="ns:EntityIdType" name="Id" minOccurs="0"/> * <xs:element name="ReportedResource"> * <xs:complexType> * <xs:choice> * <xs:element type="ns:TimeCardPersonType" name="Person"/> * <xs:element name="Resource"> * <!-- Reference to inner class Resource --> * </xs:element> * </xs:choice> * </xs:complexType> * </xs:element> * ... */public class TimeCardType{ private EntityIdType id; private int reportedResourceSelect = -1; private final int REPORTED_RESOURCE_PERSON_CHOICE = 0; private final int RESOURCE_CHOICE = 1; private TimeCardPersonType reportedResourcePerson; private Resource resource; ... private void setReportedResourceSelect(int choice) { if (reportedResourceSelect == -1) { reportedResourceSelect = choice; } else if (reportedResourceSelect != choice) { throw new IllegalStateException( "Need to call clearReportedResourceSelect() before changing existing choice"); } } /** * Clear the choice selection. */ public void clearReportedResourceSelect() { reportedResourceSelect = -1; } /** * Check if ReportedResourcePerson is current selection for choice. * * @return <code>true</code> if selection, <code>false</code> if not */ public boolean ifReportedResourcePerson() { return reportedResourceSelect == REPORTED_RESOURCE_PERSON_CHOICE; } /** * Get the "Person" element value. * * @return value */ public TimeCardPersonType getReportedResourcePerson() { return reportedResourcePerson; } /** * Set the "Person" element value. * * @param reportedResourcePerson */ public void setReportedResourcePerson( TimeCardPersonType reportedResourcePerson) { setReportedResourceSelect(REPORTED_RESOURCE_PERSON_CHOICE); this.reportedResourcePerson = reportedResourcePerson; } /** * Check if Resource is current selection for choice. * * @return <code>true</code> if selection, <code>false</code> if not */ public boolean ifResource() { return reportedResourceSelect == RESOURCE_CHOICE; } /** * Get the "Resource" element value. * * @return value */ public Resource getResource() { return resource; } /** * Set the "Resource" element value. * * @param resource */ public void setResource(Resource resource) { setReportedResourceSelect(RESOURCE_CHOICE); this.resource = resource; }