【问题标题】:how to rename nested classes in jaxb xjc如何重命名 jaxb xjc 中的嵌套类
【发布时间】:2014-09-17 15:45:45
【问题描述】:

我有一个导入架构的 wsdl 我正在尝试解决 xjc 命名多个具有相同名称的嵌套 MyElementName 类 - 这不会编译 我在下面创建了这个绑定文件,但它给出了错误:

parsing a schema...
compiling a schema...
Exception in thread "main" java.lang.IllegalArgumentException: Illegal class inheritance loop.  
Outer class MyElementName1 may not subclass from inner class: MyElementName1
    at com.sun.codemodel.internal.JDefinedClass._extends(JDefinedClass.java:257)
    at com.sun.tools.internal.xjc.generator.bean.ImplStructureStrategy$1._extends(ImplStructureStrategy.java:104)
    at com.sun.tools.internal.xjc.generator.bean.BeanGenerator.<init>(BeanGenerator.java:197)
    at com.sun.tools.internal.xjc.generator.bean.BeanGenerator.generate(BeanGenerator.java:151)
    at com.sun.tools.internal.xjc.model.Model.generateCode(Model.java:275)
    at com.sun.tools.internal.xjc.Driver.run(Driver.java:342)
    at com.sun.tools.internal.xjc.Driver.run(Driver.java:184)
    at com.sun.tools.internal.xjc.Driver._main(Driver.java:107)
    at com.sun.tools.internal.xjc.Driver.access$000(Driver.java:64)
    at com.sun.tools.internal.xjc.Driver$1.run(Driver.java:87)

我删除了 MyElementName1 的第一个绑定,它可以正常工作,但只有 1 个类的名称,我想更改这两个名称, 如何更改绑定文件,以便将两个旧嵌套类正确命名为我在下面选择的两个唯一名称。我想这样做是因为我有其他具有 4 个同名嵌套类的映射,因此需要能够命名每个类来解决更多嵌套的问题区域

<jaxb:bindings 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jaxb:bindings schemaLocation="MYWSDL.wsdl">    
        <jaxb:bindings node="//xsd:element[@name='AAAA']//xsd:complexType//xsd:sequence/xsd:element[@name='BBB']//xsd:complexType/xsd:sequence//xsd:element[@name='MyElementName']">
            <jaxb:class name="MyElementName1"/>
        </jaxb:bindings>               
        <jaxb:bindings node="//xsd:element[@name='AAAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='MyElementName']//xsd:sequence/xsd:element[@name='CCC']//xsd:sequence/xsd:element[@name='MyElementName']/xsd:complexType">
            <jaxb:class name="MyElementName2"/>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

这里是 xsd(字段名称已更改但保持不变)

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element minOccurs="0" name="AAA">
<xsd:complexType> 
    <xsd:element minOccurs="0" name="BBB">
     <xsd:complexType> 
          <xsd:element name="MyElementName">        
             <xsd:complexType>              
              <xsd:sequence>
                <xsd:element minOccurs="0" name="CCC">
                  <xsd:complexType>
                    <xsd:sequence>
                      <xsd:element name="MyElementName">
                        <xsd:complexType>
                          <xsd:sequence>
                            <xsd:element ref="FromDate" />
                            <xsd:element ref="ThruDate" />
                          </xsd:sequence>
                        </xsd:complexType>
                      </xsd:element>
                      <xsd:element name="DDD">
                        <xsd:complexType>
                          <xsd:sequence>
                            <xsd:element ref="DueDate" />
                          </xsd:sequence>
                        </xsd:complexType>
                      </xsd:element>
                    </xsd:sequence>
                  </xsd:complexType>
                </xsd:element>
                <xsd:element minOccurs="0" ref="YYYY" />
                <xsd:element minOccurs="0" ref="ZZZZ" />
                </xsd:element>
              </xsd:sequence>
            </xsd:complexType>
        </xsd:element>
    </xsd:complexType>             
    </xsd:element>               
</xsd:complexType>             
</xsd:element>  
</xsd:schema>     

字段 MyElementName2 没问题,如果我尝试在下面绑定,它会内置到 java 文件中,它只是 jaxb 映射到多个子级的第一个 - 包括使用 MyElementName2 映射的那个。 XPath 总是映射到一个节点,所以它可能是一个 jaxb 选项,因为它似乎正在扩展输入

这是导致以下错误的替代绑定

<jaxb:bindings 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
    version="2.1">
    <jaxb:bindings schemaLocation="MYWSDL.wsdl">    
        <jaxb:bindings node="//xsd:element[@name='AAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='MyElementName']">
            <jaxb:class name="MyElementName1"/>
        </jaxb:bindings>        
        <jaxb:bindings node="//xsd:element[@name='AAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='Billing']//xsd:sequence/xsd:element[@name='CCC']//xsd:sequence/xsd:element[@name='MyElementName']/xsd:complexType">
            <jaxb:class name="MyElementName2"/>
        </jaxb:bindings>
    </jaxb:bindings>
</jaxb:bindings>

错误:

parsing a schema...
[ERROR] XPath evaluation of "//xsd:element[@name='AAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='MyElementName']" results in too many target nodes
Failed to parse a schema.

【问题讨论】:

  • 除非您提供 XML Schema 以便它可以与您在绑定文件中使用的 XPath 表达式匹配,否则没有人可以检查您在做什么。 --- XML Schema 似乎具有深度嵌套的匿名类型,这很糟糕。你能改变它吗?这并不意味着改变 XML 结构!
  • 我无法提供 xml 架构或将其修改为专有的,并用于与不更改交互。我可能会用 jaxb 标签来模拟它只是为了获取代码,但这对于未来的变化来说会是一团糟
  • 如果您不想,或者甚至不能重构(通过重命名)XML Schema 的相关部分,那么我认为没有人可以帮助您。
  • 似乎在您的绑定文件中缺少一些“/”...但是您可以添加您的 xsd 吗?为了更好地帮助您。
  • 现在我切换到 xmlbeans,没有足够的可靠信息来说明这些类型的条件与 jaxb 的可靠性和快速周转

标签: java binding jaxb xjc


【解决方案1】:

JAXB 为每个复杂类型生成一个类,因此我认为您应该将自定义类名称绑定到 xs:complexType 而不是 xs:element。您的第一个 XPath 指的是 xs:element,我认为 JAXB 不知道如何将类绑定到它。试试这个绑定:

<jaxb:bindings 
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
version="2.1">
<jaxb:bindings schemaLocation="MYWSDL.wsdl">    
    <jaxb:bindings node="//xsd:element[@name='AAAA']//xsd:complexType//xsd:sequence/xsd:element[@name='BBB']//xsd:complexType/xsd:sequence//xsd:element[@name='MyElementName']/xs:complexType">
        <jaxb:class name="MyElementName1"/>
    </jaxb:bindings>               
    <jaxb:bindings node="//xsd:element[@name='AAAA']//xsd:sequence/xsd:element[@name='BBB']//xsd:element[@name='MyElementName']//xsd:sequence/xsd:element[@name='CCC']//xsd:sequence/xsd:element[@name='MyElementName']/xsd:complexType">
        <jaxb:class name="MyElementName2"/>
    </jaxb:bindings>
</jaxb:bindings>

就个人而言,我更喜欢使用 JAXB 而不是 XMLBeans。您应该小心后者,因为在编译深度嵌套模式时,它可能会生成嵌套类的结构,由于文件名长度限制(通常为 255 个字符)而无法编译。

【讨论】:

    【解决方案2】:

    您的 XPath:

    //xsd:element[@name='AAA']
    //xsd:sequence/xsd:element[@name='BBB']
    //xsd:element[@name='MyElementName']
    

    似乎指的是您的两个MyElementName 元素,因为它们都在BBB 下。尝试摆脱//

    //xsd:element[@name='AAA']
    /xsd:complexType
    /xsd:sequence
    /xsd:element[@name='BBB']
    /xsd:complexType
    /xsd:sequence
    /xsd:element[@name='MyElementName']
    

    我认为这是正确的方向。您必须自定义匿名内部复杂类型。

    【讨论】:

      猜你喜欢
      • 2016-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-06
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      相关资源
      最近更新 更多