Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding extra methods to a JAXB class generated from schema

Tags:

java

jaxb

Here's a trivial excerpt from my XSD file

<?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>

I use the maven-jaxb2-plugin to generate Java classes from this. The Document class has a getTitle() method to return the text of the title attribute.

I want to add an additional method to Document:

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

I want my extra method to appear on the unmarshalled object (rather than me just calling it or writing a wrapper class) because I want to pass the top-level unmarshalled object off to a string template and have it iterate over sub-elements calling my extra method.

I found instructions but they tell me to set a property on the Unmarshaller and my (Mac OS X, Java 7) implementation doesn't appear to support any properties.

How should I do this?

like image 224
Nathaniel Waisbrot Avatar asked Jan 11 '13 20:01

Nathaniel Waisbrot


People also ask

Which component or tool in JAXB can generate Java files from schemas?

After the Java artifacts for your application are generated, you can generate fully annotated Java classes from an XML schema file by using the JAXB schema compiler, xjc command-line tool.

How do you use XJC generated classes?

Open a command prompt. Run the JAXB schema compiler, xjc command from the directory where the schema file is located. The xjc schema compiler tool is located in the app_server_root \bin\ directory. Use the generated JAXB objects within a Java application to manipulate XML content through the generated JAXB classes.

What is JAXB marshalling and Unmarshalling?

JAXB definitionsMarshalling is the process of transforming Java objects into XML documents. Unmarshalling is the process of reading XML documents into Java objects. The JAXBContext class provides the client's entry point to the JAXB API. It provides API for marshalling, unmarshalling and validating.


1 Answers

Following the link the Brian Henry gave, I found I could perform binding customization inline in my schema file to do what I wanted. The effect is exactly the same as Brian's solution, but it doesn't require a reference to a reference to com.sun.xml.internal.

First, the schema file gets modified somewhat:

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

When the schema gets compiled into Java code, the generated ObjectFactory will refer to DocumentEx instead of Document. DocumentEx is a class I create, which looks like this:

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

Document (the class I'm extending) is still generated by the schema-to-Java compiler. Now when I unmarshall a document I actually get a DocumentEx object:

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

There is some (hard-to-parse) documentation for this at Oracle and some helpful examples at O'Reilly.

like image 109
Nathaniel Waisbrot Avatar answered Oct 14 '22 05:10

Nathaniel Waisbrot