重命名JAXB生成的類名方法名

JAXB把schema轉換成java class的時候,會自動生成類名,方法名。在有些時候,這些名字會出現問題,比如,schema裏面允許有同名的元素,這會導致生成的java類裏面有兩個同名的成員,顯然是不對的。除此之外,JAXB自動生成的方法名,有時候會很長,很不友好。怎麼解決這類問題?幸好jaxb提供了定製機制。

 

JAXB提供了用annotation進行擴展的機制。下面的這個例子會生成

 

如果沒有註釋部分的annotation,生成的java class會包含一個名字很長的方法:

  

把註釋部分打開,生成的方法名就體面多了:

 

下面的摘自http://jaxb.java.net/tutorial/section_5_3-Overriding-Names.html,介紹了更多類似的例子。

5.3 Overriding Names

Overriding the name of a class or of an element's child is something you may have to do to avoid name clashes. Usually it is more convenient to fix the XML schema, but you may not always be at liberty to do so.

Let's assume that you have a schema where a complex type has been given the uninspired name List:

<xsd:complexType name="List">
  <xsd:sequence>
    <xsd:element name="items" type="ItemType"
                 minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
</xsd:complexType>

JAXB's schema compiler circumnavigates the threatening name clash between this class and java.util.List, required within the generated class code for declaring the field items. But wherever this class is used it is potentially in conflict with its namesake from java.util. To avoid having to use the full class name for one of these two classes, you might override the class name for the generated class:

<xsd:complexType name="List">
  <xsd:annotation>
    <xsd:appinfo>
      <jxb:class name="MyListType"/>
    </xsd:appinfo>
  </xsd:annotation>
  <xsd:sequence>
    <xsd:element name="items" type="ItemType"
                 minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
</xsd:complexType>

Another unlucky choice for the name of an element or attribute would be Class. For this one, JAXB's workaround is the standard programmer's choice, i.e., it is replaced by Clazz. If you don't fancy this, you can request your own substitute, using an jxb:property element, like this:

<xsd:complexType name="School">
  <xsd:sequence>
    <xsd:element name="class" type="ClassType">
      <xsd:annotation>
        <xsd:appinfo>
          <jxb:property name="klass"/>
        </xsd:appinfo>
      </xsd:annotation>
    </xsd:element>
  </xsd:sequence>
</xsd:complexType>

Other Java keywords won't constitute a problem. The instance variable will be given a name consisting of an underscore followed by the letters of the keyword.

Yet another reason for changing a name arises from the use of the same name for a sub-element and an attribute within the same complex type definition. (Arguably this isn't good XML design. But, believe me, it does happen.)

<xsd:complexType name="ClassType">
  <xsd:sequence>
    <xsd:element name="grade" type="xsd:string" minOccurs="0"/>
  </xsd:sequence>
  <xsd:attribute name="grade" type="xsd:string" use="optional"/>
</xsd:complexType>

We'll resolve this conflict by renaming the attribute to gradeAttr, this time by specifying the property name in the bindings file.

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xsd="http://www.w3.org/2001/XMLSchema"
               jxb:version="2.0">
  <jxb:bindings schemaLocation="School.xsd" node="/xsd:schema">
    <jxb:bindings node="//xsd:attribute[@name='grade']">
      <jxb:property name="gradeAttr"/>
    </jxb:bindings>
  </jxb:bindings>
</jxb:bindings>

XML Schema even lets you define a sequence where two individual elements have the same tag

<xsd:complexType name="StrangeType">
  <xsd:sequence>
    <xsd:element name="taga" type="xsd:string"/>
    <xsd:element name="tagb" type="xsd:string"/>
    <xsd:element name="taga" type="xsd:string"/>
  </xsd:sequence>
</xsd:complexType>

There is no such thing as a Java class that has two distinct fields with the same name. You must help the schema compiler to resolve this conflict, by renaming either element:

    ...
    <xsd:element name="taga" type="xsd:string">
      <xsd:annotation>
        <xsd:appinfo>
          <jxb:property name="taga2"/>
        </xsd:appinfo>
      </xsd:annotation>
    </xsd:element>
    ...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章