1

I'm trying to figure out a way for how to use the same .xjb bindings file for multiple xsd files.

I found a solution here for "floating global bindings": https://www.java.net/node/674443

However, the stuff I'm trying to do does not seem to be allowed under the globalBindings tag.

Here's the binding code I have for a specific .xsd:

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
        xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance" 
        jaxb:version="2.1" 
        jaxb:extensionBindingPrefixes="xjc inheritance">
    <jaxb:bindings schemaLocation="../Specific.xsd" node="/xs:schema">
        <jaxb:bindings node="//xs:complexType[@name='entity']">
            <inheritance:implements>test.IEntity</inheritance:implements>
        </jaxb:bindings>
        <jaxb:bindings node="//xs:element[@name='entityContainer']">
            <jaxb:class/>
            <inheritance:implements>test.IEntityContainer</inheritance:implements>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

How do I now apply that to any .xsd in the xsd directory?

I have difficulty to believe that the only solution to this would be to actually generate the single binding files per xsd file (as outlined in the referenced forum entry above), or is it really?

Also note that the node xpath would in fact be a bit more complicated as there are different (types of) containers, I just simplified it here to not overcomplicate the example.

mac
  • 2,672
  • 4
  • 31
  • 43
  • You could use a generic bindings XML file and an XSLT transformation to fill in the variable parts: XSD file name, type name, element name, etc. If this appears worth the savings of having individual files, I can provide a basic solution. – laune Sep 05 '14 at 13:38
  • If you could provide an example, that would be great. Also note though please that I'm trying to run this within maven, so I'd need a way how to execute the transformation within the maven build cycle. – mac Sep 08 '14 at 19:44
  • Did you ever find a good solution to this? – bdrx Apr 28 '22 at 21:29

1 Answers1

0

This is an XSLT Transformation binding.xsl to create those binding files from a template:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xs="http://www.w3.org/2001/XMLSchema"
   xmlns:mark="/m/a/r/k"
   xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" >

  <xsl:param name = "schema"  as = "xs:string" />
  <xsl:param name = "type"    as = "xs:string" />
  <xsl:param name = "element" as = "xs:string" />

  <xsl:output indent="yes"/>

  <xsl:variable name = "apo" select = "''''" />

  <xsl:template match="/">
    <xsl:apply-templates select="*"/>
  </xsl:template>

  <xsl:template match="jaxb:bindings">
    <xsl:copy>
      <xsl:apply-templates select="*|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="jaxb:bindings[@mark:mark = 'schema']">
    <xsl:copy>
      <xsl:attribute name="schemaLocation" select='concat("../", $schema, ".xsd")'/>
      <xsl:apply-templates select="*|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="jaxb:bindings[@mark:mark = 'type']">
    <xsl:copy>
      <xsl:attribute name="node"
        select='concat("//xs:complexType[@name=", $apo, $type, $apo, "]")'/>
      <xsl:apply-templates select="*|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="jaxb:bindings[@mark:mark = 'element']">
    <xsl:copy>
      <xsl:attribute name="node"
        select='concat("//xs:element[@name=", $apo, $element, $apo, "]")'/>
      <xsl:apply-templates select="*|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@*">
    <xsl:copy-of select="."/>
  </xsl:template>
</xsl:stylesheet>

This is the template binding.xml:

<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns:inheritance="http://jaxb2-commons.dev.java.net/basic/inheritance" 
    xmlns:mark="/m/a/r/k"
    jaxb:version="2.1" 
    jaxb:extensionBindingPrefixes="xjc inheritance">
  <!-- schemaLocation="../Specific.xsd" -->
  <jaxb:bindings mark:mark="schema"  node="/xs:schema">
    <!-- node="//xs:complexType[@name='entity'] -->
    <jaxb:bindings mark:mark="type" >
      <inheritance:implements>test.IEntity</inheritance:implements>
    </jaxb:bindings>
    <!-- node="//xs:element[@name='entityContainer']" -->
    <jaxb:bindings mark:mark="element">
      <jaxb:class/>
      <inheritance:implements>test.IEntityContainer</inheritance:implements>
    </jaxb:bindings>
  </jaxb:bindings>
</jaxb:bindings>

You can execute this using Saxon HE, to be invoked like this (single shell command), with the last three arguments to be varied according to your many XML Schema files.

java -cp /extra/saxon/saxon9he.jar net.sf.saxon.Transform \
   -s:binding.xml -xsl:binding.xsl \
    schema=Specific type=entity element=entityContainer

It shouldn't be a problem to call this from maven

laune
  • 31,114
  • 3
  • 29
  • 42