Welcome 微信登录

首页 / 软件开发 / JAVA / JiBX 1.2,第2部分: 从XML模式到Java代码(二)

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;  }