向模式生成的JAXB类添加额外的方法

时间:2013-01-11 20:13:10

标签: java jaxb

这是我的XSD文件中的一个简单的摘录

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="ns"
    xmlns:tns="sns" elementFormDefault="qualified">

  <element name="document">
        <attribute name="title" use="required"/>
  </element>
</schema>

我使用maven-jaxb2-plugin从中生成Java类。 Document类使用getTitle()方法返回title属性的文本。

我想为Document添加一个额外的方法:

public String getStrippedTitle() {
   return getTitle().replaceAll("\\s+", "");
}

我希望我的额外方法出现在unmarshalled对象上(而不是我只是调用它或编写一个包装类),因为我想将顶级的unmarshalled对象传递给一个字符串模板并让它迭代调用我的额外方法的元素。

我找到了instructions,但是他们告诉我在Unmarshaller设置属性,而我的(Mac OS X,Java 7)实现似乎不支持任何属性。

我该怎么做?

2 个答案:

答案 0 :(得分:7)

在Brian Henry给出的链接之后,我发现我可以在我的模式文件中内联绑定自定义来执行我想要的操作。效果与Brian的解决方案完全相同,但它不需要引用com.sun.xml.internal的引用。

首先,模式文件有所修改:

<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="ns"
    xmlns:tns="sns" elementFormDefault="qualified"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.0">

  <element name="document">
      <annotation>
          <appinfo>
              <jaxb:class implClass="DocumentEx" />
          </appinfo>
      </annotation>
      <attribute name="title" use="required"/>
  </element>
</schema>

当架构编译成Java代码时,生成的ObjectFactory将引用DocumentEx而不是DocumentDocumentEx是我创建的类,如下所示:

public class DocumentEx extends Document {
   public String getStrippedTitle() {
       return getTitle().replaceAll("\\s+", "");
   }
}

Document(我正在扩展的类)仍由schema-to-Java编译器生成。现在,当我解组文档时,我实际上得到了一个DocumentEx对象:

    JAXBContext jaxbContext = JAXBContext.newInstance("com.example.xml");
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    unmarshaller.setSchema(testSchema);
    DocumentEx doc = (DocumentEx)unmarshaller.unmarshal(xmlFile);

Oracle处有一些(难以解析的)文档以及O'Reilly处的一些有用示例。

答案 1 :(得分:2)

您可以尝试更新您在链接文档中看到的属性名称。试试这个:

com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.FACTORY

"com.sun.xml.internal.bind.ObjectFactory"

我猜这会让你超越我看到的PropertyException。最彻底的答案here表明这不能保证有效,但值得尝试,因为你已经到了这么远。源代码,据我看(不远)似乎支持这个属性。