繁体   English   中英

如何强制模式编译的类扩展模式外的特定类

[英]how to force schema compiled classes to extend specific class outside schema

需要以下情况的帮助:用户可以生成自己的数据结构,这些数据结构存储为JAXB-ready XSD源,如下所示:

<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:element name="Group" type="Group"/>
  <xs:element name="Parameter" type="Parameter"/>

  <xs:complexType name="Group">
    <xs:sequence>
      <xs:element name="caption" type="xs:string" minOccurs="0"/>
      <xs:element name="parameters" type="Parameter" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="Parameter">
    <xs:sequence>
      <xs:element name="key" type="xs:string" minOccurs="0"/>
      <xs:element name="group" type="Group" minOccurs="0"/>
      <xs:element name="value" type="xs:string" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

在出现新的或修改的模式之后,它将由Schema编译器自动解析,生成,编译和打包到用户jar的java源:

  SchemaCompiler sc = XJC.createSchemaCompiler();
  // Input source for schema
  InputSource is = new InputSource(new StringInputStream(objectPackage.getObjectSchema()));
  // Parse
  sc.parseSchema(is);
  S2JJAXBModel model = sc.bind();
  // Generate source
  JCodeModel jCodeModel = model.generateCode(null, null);
  jCodeModel.build(packageSourceDirectory);
  // Compile and package 
  // ......

一切都很好,直到确定所有用户生成的类必须扩展一个特定的已知类,比如UserRootObject

package user.abc;
public class Group extends com.mycompany.xml.UserRootObject {
  //
}

package user.abc;
public class Parameter extends com.mycompany.xml.UserRootObject {
  //
}

一切都在飞行中,我不能强迫用户修改他们的模式文件,但我可以在代码生成之前对其进行转换。 看起来我有两个选项来介绍UserRootObject :以某种方式通过JCodeModel或以某种方式转换模式文件,然后再构建Java源代码。

XJC为此目的有一个扩展

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
           xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
           jaxb:extensionBindingPrefixes="xjc"
           jaxb:version="2.0">

    <xs:annotation>
       <xs:appinfo>
          <jaxb:globalBindings>
           <xjc:superClass name="com.mycompany.xml.UserRootObject"/>
          </jaxb:globalBindings>
       </xs:appinfo>
    </xs:annotation>
.
.
.
</xs:schema>

有关更多信息,请参阅

模式注释也可以通过外部绑定文件提供。 有关示例,请参阅:

非常感谢D.Shawley指出JSR 222中的正确部分。这是最终解决方案,可能对其他人有帮助并节省时间。 原始模式必须转换如下:

    <xs:schema version="1.0" 
               xmlns:xs="http://www.w3.org/2001/XMLSchema" 
               xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
               jaxb:version="2.0" >

      <xs:element name="Group" type="Group"/>
      <xs:element name="Parameter" type="Parameter"/>


      <xs:complexType name="Group">
        <xs:complexContent>
          <xs:extension base="UserRootObject">
            <xs:sequence>
            <!-- params -->
            </xs:sequence>
          </xs:extension>
        </xs:complexContent>
      </xs:complexType>

      <xs:complexType name="Parameter">
        <xs:complexContent>
          <xs:extension base="UserRootObject">
            <xs:sequence>
            <!-- params -->
            </xs:sequence>
          </xs:extension>
        </xs:complexContent>
      </xs:complexType>

      <xs:complexType name="UserRootObject">
        <xs:annotation>
          <xs:appinfo>
            <jaxb:class name="UserRootObject" implClass="com.mycompany.xml.UserRootObject"/>
          </xs:appinfo>
        </xs:annotation>
      </xs:complexType>
    </xs:schema>

可以通过org.w3c.dom.Document inteface轻松执行转换。

我不相信使用JAXB本身有一种简单的方法。 有许多不常见的自定义选项 - 有关详细信息,请参阅JSR222的第7节

如果您可以控制输入模式,那么您可能需要考虑使用XSLT来转换模式。 我相信这可以通过使用javax.xml.transform.dom.DOMResult实例作为转换的目标并将输出用作DOM树(例如,在结果上调用getNode() )作为parseSchema的输入来parseSchema 一个基本的转变将是取代:

<xs:complexType name="foo">
  <!-- CONTENTS -->
</xs:complexType>

有类似的东西:

<xs:complexType name="foo">
  <xs:complexContent>
    <xs:extension base="UserRootObject">
      <!-- CONTENTS -->
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

当然这只适用于简单的情况。 如果您已在模式文件中具有继承,则必须在XSLT中执行一些过滤,该过滤仅将此变换应用于尚未扩展的类型。

这是一个古老的话题,但只是为了记录:

您可以使用jaxb2继承插件执行此操作。 像这样:

<xs:complexType name="...">
  <xs:annotation>
    <xs:appinfo>
      <inheritance:extends>
         com.mycompany.xml.UserRootObject
      </inheritance:extends>
    </xs:appinfo>
  </xs:annotation>
  <!-- ... -->
</xs:complexType>

例如,请参见http://vistaofjavahorizo​​n.blogspot.com/2014/07/how-to-have-particular-java-class.html

在线有更多的例子。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM