将JAXB2生成的对象强制转换为JAXBElement?

将JAXB2生成的对象强制转换为JAXBElement?,jaxb,Jaxb,我有两套XSD,一套生成基于RPC的调用,另一套定义特定于产品的方法。RpcType对象(由JAXB2生成)有一个“setRpcOperation”方法,该方法由以下内容定义: RpcType.setRpcOperation(JAXBElement<? extends RpcOperationType>) 现在,是否可以创建“GetUserStatus”的实例并通过SetrCoperation将其添加到RpcType对象中?这种情况很常见: 一个模式来表示消息 表示有效负载的多个

我有两套XSD,一套生成基于RPC的调用,另一套定义特定于产品的方法。RpcType对象(由JAXB2生成)有一个“setRpcOperation”方法,该方法由以下内容定义:

RpcType.setRpcOperation(JAXBElement<? extends RpcOperationType>)

现在,是否可以创建“GetUserStatus”的实例并通过SetrCoperation将其添加到RpcType对象中?

这种情况很常见:

  • 一个模式来表示消息
  • 表示有效负载的多个架构
以下是一种方法:

消息架构-Message.xsd

有一个XML模式来表示您的消息信封。引入一种类型来表示消息体。该类型将通过不同的有效载荷进行扩展

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
   targetNamespace="http://www.example.org/message" 
   xmlns="http://www.example.org/message" 
   elementFormDefault="qualified">

    <xsd:element name="message">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="body" type="body"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

    <xsd:complexType name="body">
    </xsd:complexType>

</xsd:schema>
org.example.message.message

此类是从message.xsd生成的

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/message", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.example.message;
package org.example.message;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "body"
})
@XmlRootElement(name = "message")
public class Message {

    @XmlElement(required = true)
    protected Body body;

    public Body getBody() {
        return body;
    }

    public void setBody(Body value) {
        this.body = value;
    }

}
package org.example.message;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "body")
public class Body {

}
org.example.message.Body

此类是从message.xsd生成的

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/message", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.example.message;
package org.example.message;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "body"
})
@XmlRootElement(name = "message")
public class Message {

    @XmlElement(required = true)
    protected Body body;

    public Body getBody() {
        return body;
    }

    public void setBody(Body value) {
        this.body = value;
    }

}
package org.example.message;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "body")
public class Body {

}
org.example.customer.package info

此类是从customer.xsd生成的

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/customer", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.example.customer;
package org.example.customer;

import javax.xml.bind.annotation.*;
import org.example.message.Body;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "customer", propOrder = {
    "name"
})

public class Customer extends Body {

    @XmlElement(required = true)
    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

}
org.example.customer.customer

此类是从customer.xsd生成的

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.org/customer", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.example.customer;
package org.example.customer;

import javax.xml.bind.annotation.*;
import org.example.message.Body;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "customer", propOrder = {
    "name"
})

public class Customer extends Body {

    @XmlElement(required = true)
    protected String name;

    public String getName() {
        return name;
    }

    public void setName(String value) {
        this.name = value;
    }

}
演示类

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

import org.example.customer.*;
import org.example.message.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Message.class, Customer.class);

        Message message = new Message();
        Customer customer = new Customer();
        customer.setName("Jane Doe");
        message.setBody(customer);

        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(message, System.out);
    }
}
输出

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<message xmlns="http://www.example.org/message" xmlns:ns2="http://www.example.org/customer">
    <body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="ns2:customer">
        <ns2:name>Jane Doe</ns2:name>
    </body>
</message>
编辑#2

将导入更改为导入后,我看到了与您相同的行为

要正确设置属性,您需要执行以下操作:

RpcType rpc = new RpcType(); 
GetFailedLoginCount rpcOperation = new GetFailedLoginCount(); 
rpcOperation.setReset(true);
JAXBElement<GetFailedLoginCount> rpcOperationJE = new JAXBElement(new QName("foo"), GetFailedLoginCount.class, rpcOperation);
rpc.setRpcOperation(rpcOperationJE);
RpcType rpc=new RpcType();
GetFailedLoginCount rCoperation=新建GetFailedLoginCount();
rpcOperation.setReset(真);
JAXBElement rpcopeonje=新的JAXBElement(新的QName(“foo”),GetFailedLoginCount.class,rpcOperation);
rpc.setRpcOperation(rpcOperationJE);
JAXBElement为GetFailedLoginCount值提供元素名。这是必需的,因为与rpcOperation属性对应的元素是可替换的:

<xs:element name="get-config" type="getConfigType" substitutionGroup="rpcOperation" /> 

在导入netconf.xsd的模式中,应该有一个类型为“get failed login count”的元素,该元素可以替换为“rpcOperation”。这将作为QName提供给JAXBElement。由于我们在模式更新上面使用了元素名“foo”,因此该模式更新如下所示:

<xs:element name="foo" type="get-failed-login-count" substitutionGroup="rpcOperation" /> 

好的,下面是我要做的部分。上面的示例非常有用,但我仍然无法创建JAXBElement:

可以找到基本信封:

RPCopeOptionType的有效负载(我添加了**行):


**
**
** 
获取身份验证失败的登录计数失败,超出了用户权限
此命令返回由于超过允许的限制和身份验证失败而被拒绝的登录数(24小时移动窗口)
登录计数失败
重置统计数据
这将控制此统计数据的重置。默认情况下,数据不会重置。
** 
**
现在,生成的GetFailedLogin类扩展了rpCopeOptionType,但我不确定如何在RpcType对象中设置它:

    RpcType rpc = new RpcType();
    rpc.setMessageId("123");
    GetFailedLoginCount rpcOperation = new GetFailedLoginCount();
    rpc.setRpcOperation(); // Expects JAXBElement<? Extends RpcOperationType>
RpcType rpc=new RpcType();
rpc.setMessageId(“123”);
GetFailedLoginCount rCoperation=新建GetFailedLoginCount();

rpc.setRpcOperation();//希望JAXBElementis在xsd中有一种实现#1的方法吗?对于#2,似乎所有3个选项都是一样的……我也在我的博客上发布了一个示例,其中消息对象具有object类型的属性,并利用@XmlAnyElement注释来整理负载:我根据您的第二篇文章更新了我的答案。这是我通过XJC运行这些模式时得到的方法签名:public void setRpcOperation(RpcOperationType值)是的,使用它我得到了相同的结果。不要使用我粘贴的内容,而是使用完整的netconf.xsd from:它将生成函数how i see it:public void setRpcOperation(JAXBElementThanks感谢所有帮助…现在我得到了一个“[com.sun.istack.SAXException2:无法封送类型“netconf.RpcType”作为元素,因为它缺少@XmlRootElement注释]'我确信这与所描述的问题是一样的:,但我正在尝试尽可能少地修改XSD。关于如何解决这个问题,有什么想法吗?这是一个问题还是一个答案?问题…最后一行'rpc.setRpcOperation();'需要传递一些内容…rpcOperation对象是否可能键入JAXBElement