Mule and JAXB: turning an XSD file into an XML Fiesta!

motif

Hello friends! How’s it going?

Has the following ever happened to you? You show up to work one morning and your boss tells you, “I need you to take this data and turn it into .” Well, this has happened to me, and in this blog post I’m going to show you how to do this quickly.

XSD?

In all fairness to my boss, he did give me an XSD file describing the structure of the XML I was asked to generate. But what is an XSD file anyway?

XSD stands for XML Schema Definition. It’s nothing but another XML file of a known and canonical format which is used to describe the structure of another XML file. For example, if I want to dump an employee’s data into an XML, the XSD’s job is to let everyone know that an employee must have a name, an address, a social security number, that he can hold several positions in the same organization and so forth… But most importantly, it describes the layout of all that data in the XML file.

Here’s a sample XSD example for your reference describing an employees XML:

Generating objects

But, who cares? What’s the use of an XSD file? Well, for starters, your IDE probably uses XSD files to validate that the XML files you write are valid (this is true for example when working with Spring, Hibernate, and of course Mule ESB). But it could also be used for automatic mapping and code generation. What does is to read the XSD file to automatically generate a set of classes that mimic the structure of the XML and that allows for storing the same data in the same way. Once those classes exists, it’s easy for to marshall XML data into those objects and vice versa.

JAXB has a terminal command that takes an XSD file and turns it into a Java Bean. This command is called XJC and is present on the bin/ folder of any JDK installation since version 1.6. Here’s a sample of how to use it:

The command above will create a java class with the proper JAXB annotations to perform XML marshalling and unmarshalling. It will also create a second class called ObjectFactory, which it will use internally when performing the transformations. You need to add these classes into your project. For simplicity let’s assume that you put them in the package com.mulesoft.example.

Then it’s just a matter of populating the bean and using Mule’s JAXB Transformers to generate the XML. Sample code looks as follows:

That’s it. You just made your boss happy. Do you really want to impress him though? Let’s also see how you can do the reverse operation and transform an XML file into a Java Object.
Mule already provides an object-to-xml-transformer out of the box and it would work just fine in this case, but just for the sake of completeness, let’s see how you can do the same thing using JAX

And that’s it! You’re all set! Now show it to your boss and get him to buy you beer!


We'd love to hear your opinion on this post

18 Responses to “Mule and JAXB: turning an XSD file into an XML Fiesta!”

  1. […] Mule and JAXB: turning an XSD file into an XML Fiesta! […]

    Agree(0)Disagree(0)Comment
  2. Hi Mariano,
    Thanks for this post. I have the same problem with my boss but I want to generate xsd from tables using mule, have you done that?
    Actually the whole problem area is really complicated for me and part of it is to generate xsd from tables. Are you willing to hear my story?
    BR

    Agree(0)Disagree(0)Comment
    • Hello Sherry, so your boss wants to make you work as well? They’ll never learn… 😀

      So now seriously, the use case that you mention is indeed tricky. I did some googling around it and found some links about how to do this with Oracle and SQLServer, you can probably find it yourself if you get into google with q=generate xsd from table. However, all of those solutions are very database specific and some quite complicated to customize if you’re not a DBA or an expert on each engine’s scripting language (not to mention application portability….). My advice to you is to use the out of the box support that Java gives you for XML through JAX. How would that work? Create Java Objects that represents your tables and annotate them with JAX annotations that describe how you would like the data to be mapped into the xml format. Then use the generateschema tool that comes bundled with any JDK1.6 to generate the xsd. There’s a very good article about how to do this here http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Ftwbs_jaxbjava2schema.html.

      Now, as far as Mule support comes, I don’t think we currently hava out of the box support for doing this (I might be wrong though and this is an excellent question to ask on the forum). However, it should be easy to write a Mule extension that generates the XSD using DevKit. And of course, If you already have JAX annotated classes on your project, you can use the JAX support that is already described on this article.

      I hope this helps you. If it doesn’t please reach out again and I’ll be more than happy to hear your story.

      Best,

      Agree(0)Disagree(0)Comment
  3. Hi Mariano,
    Thanks for your reply. Is it possible for you to just give me your email to send you the whole scenario, are you interested at all? If not can i ask my questions here because i think you are the only person that can help me to accomplish this task
    Regards,
    Sherry

    Agree(0)Disagree(0)Comment
  4. Hi Mariano,
    I have a similar scenario.
    I am trying to create an HTTP inbound endpoint, but with my own XML schema for input and output data.
    Can you explain me how to apply it (the XSD) to a HTTP request/response endpoint???

    Best regards,
    Juan

    Agree(0)Disagree(0)Comment
    • Hello Juan,

      If what you’re expecting is a http request carrying XML in its body, then Mule with place that XML in the message payload. So, what I’d do is using the xjc command to generate objects form your XSD and then you could have a flow that pretty much looks like this:

      
      <flow name="juanFlow">
           <http:inbound -endpoint path="xml" />
            <mulexml:jaxb -xml-to-object-transformer ...... />
            
             <!-- do your logic -->
      
              <mulexml:jaxb -object-to-xml-transformer ..... />
      </flow>
      

      As you can see, this is only pseudo code since I don’t know the details of your scenario, but it’s pretty much the structure I’d follow. Also, I think you could benefit from taking a look at mule’s XML module documentation at http://www.mulesoft.org/documentation/display/MULE3USER/XML+Module+Reference . Maybe some of the tools described there could provide a simpler solution depending on your scenario.

      Let me know how that works for you!

      Agree(0)Disagree(0)Comment
  5. Hello Mariano,

    I still do not understand something…
    In my scenario i have the following XSD:

    Having a quick explanation, with the input I want to select some data from a data base and return it as the output specification.
    So, I have not clear how the HTTP endpoint knows how to take the input and return the response.

    Juan

    Agree(0)Disagree(0)Comment
  6. Here is the XSD:

    Agree(0)Disagree(0)Comment
  7. I dont know why the XSD does not appear…

    Agree(0)Disagree(0)Comment
    • Juan,

      For your XSD to show you need to enclose it into <code> tags.

      As for your question, what the http endpoint will do is to put the body of the input request into the message payload. From there, you can transform that xml to objects, edit them, go to the database using the JDBC transport or any other component you like. As for the response, whatever is in the message payload at the end of the flow is what will be returned, just make sure to set the endpoint’s exchange pattern to “request-response”.

      If you have further doubts on how a Mule flow works, I think you could benefit from reading this blog post

      Please let me know if you have additional questions.

      Cheers

      Agree(0)Disagree(0)Comment
  8. Where on earth is the jaxb transformer? I can’t find it in version 3.3.0 CE there is a “xml-to-object-transformer” but no “jaxb-xml-to-object-transformer” in sight. How do you configure the first one for Jaxb?

    Agree(0)Disagree(0)Comment
  9. Hello Packman,

    The jaxb transformer is on the mule-module-xml library. You should already have it on the lib directory of your mule installation but you can also get it through this maven dependency:


    org.mule.modules
    mule-module-xml
    3.3.0

    Also remember to include the namespaces on your configuration file. This is the xml namespace declaration:

    xmlns:mulexml=”http://www.mulesoft.org/schema/mule/xml”

    and this is the location:

    http://www.mulesoft.org/schema/mule/xml http://www.mulesoft.org/schema/mule/xml/3.3.0/mule-xml.xsd

    Agree(0)Disagree(0)Comment
  10. Hey Mariano,

    I can successfully get my objects to transform from XML to Objects, and subsequently to JSON.

    I can not however get my objects to transform from XML to Object back to XML, or any Object back to XML. Any ideas:

    Example code snippets:


    This is successful


    This is not :(

    Example fault:
    Message : Could not find a transformer to transform “SimpleDataType{type=java.io.ByteArrayOutputStream, mimeType=’application/xml’}” to “SimpleDataType{type=org.mule.api.transport.OutputHandler, mimeType=’*/*’}”.
    Code : MULE_ERROR-65237

    Agree(0)Disagree(0)Comment
  11. I guess it took out my xml, lets try again:

    Example code snippets:
    mulexml:jaxb-context name=”myObjectFactory” packageNames=”com.company”

    This is successful
    mulexml:jaxb-xml-to-object-transformer name=”XmlToObject” jaxbContext-ref=”myObjectFactory” returnClass=”com.myCompany.MyObject”

    This is not :(
    mulexml:jaxb-object-to-xml-transformer name=”ObjectToXml” jaxbContext-ref=”myObjectFactory”

    Example fault:
    Message : Could not find a transformer to transform “SimpleDataType{type=java.io.ByteArrayOutputStream, mimeType=’application/xml’}” to “SimpleDataType{type=org.mule.api.transport.OutputHandler, mimeType=’*/*’}”.
    Code : MULE_ERROR-65237

    Agree(0)Disagree(0)Comment
  12. Snooker, I think the problem is that at the moment of executing the object-to-xml-transformer, the message payload is an output stream. As shown in the example above, a pojo is required instead (notice that an output stream doesn’t have properties and cannot be annotated).

    Please try it making sure that a pojo is at the payload at that moment and let me know how that works for you.

    Best,

    Agree(0)Disagree(0)Comment
  13. Thanks for the reply!

    I found that the transformation was actually working, the issue was on the outbound endpoint. I had to convert the output stream to a string based on how I had my endpoint configuration.

    Agree(0)Disagree(0)Comment