如何为多个xsds重用jaxb绑定?

时间:2014-09-04 04:12:43

标签: java jaxb xjc jaxb2-maven-plugin

我试图想办法为多个xsd文件使用相同的.xjb绑定文件。

我在这里找到了一个解决方案,用于"浮动全局绑定": https://www.java.net/node/674443

然而,我试图做的事情似乎不允许在globalBindings标签下。

这是我对特定.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>

我现在如何将其应用于xsd目录中的任何.xsd?

我很难相信这个问题的唯一解决方案是实际生成每个xsd文件的单个绑定文件(如上面引用的论坛条目所述),还是真的?

另请注意,由于存在不同(类型)的容器,节点xpath实际上会有点复杂,我在这里简化它以使示例不会过于复杂。

1 个答案:

答案 0 :(得分:0)

这是一个XSLT Transformation binding.xsl,用于从模板创建这些绑定文件:

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

这是模板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>

您可以使用Saxon HE执行此操作,以此方式调用(单shell命令),最后三个参数将根据您的许多XML Schema文件进行更改。

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

从maven

调用它应该不是问题