2010-08-25 19 views
3

我有兩組XSD,一個生成基於RPC的調用,另一個定義特定於產品的方法。所述RpcType對象(通過JAXB2產生)具有由下式定義一個「setRpcOperation」方法:將JAXB2生成的對象轉換爲JAXBElement?

RpcType.setRpcOperation(JAXBElement<? extends RpcOperationType>) 

那RpcOperation'對象應是上述的特定產品的方法「。一個例子是(也由JAXB2生成):

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "get-user-stats", propOrder = { 
    "reset" 
}) 
public class GetUserStats { 

    protected Boolean reset; 

    /** 
    * Gets the value of the reset property. 
    * 
    * @return 
    *  possible object is 
    *  {@link Boolean } 
    *  
    */ 
    public Boolean isReset() { 
     return reset; 
    } 

    /** 
    * Sets the value of the reset property. 
    * 
    * @param value 
    *  allowed object is 
    *  {@link Boolean } 
    *  
    */ 
    public void setReset(Boolean value) { 
     this.reset = value; 
    } 

} 

現在,是有可能創造「GetUserStatus」的一個實例,它通過setRpcOperation添加到RpcType對象?

回答

3

這種類型的情況下是常見的:

  • 一個模式來表示消息
  • 多個模式來表示有效載荷。

下面是一個辦法可以這樣做:

消息模式 - 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> 

有效載荷架構 - customer.xsd

該模式對應於一個特定類型的消息有效載荷的。注意客戶類型如何從消息模式擴展正文類型。

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

    <xsd:import schemaLocation="message.xsd" namespace="http://www.example.org/message"/> 

    <xsd:complexType name="customer"> 
     <xsd:complexContent> 
      <xsd:extension base="m:body"> 
       <xsd:sequence> 
        <xsd:element name="name" type="xsd:string"/> 
       </xsd:sequence> 
      </xsd:extension> 
     </xsd:complexContent> 
    </xsd:complexType> 

</xsd:schema> 

org.example.message.package-信息

從message.xsd產生這個類。

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

org.example.message.Message

這個類是從message.xsd生成。

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; 
    } 

} 

org.example.message.Body

這個類是從message.xsd生成。

package org.example.message; 

import javax.xml.bind.annotation.*; 

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

} 

org.example.customer.package-信息

從customer.xsd生成這個類。

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

org.example.customer。客戶

該類由customer.xsd生成。

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> 

EDIT#1

在回答您的開環nd問題(Cast JAXB2 generated object to JAXBElement?

我沒有看到JAXBElement在這個例子中發揮了什麼作用。我能夠運行下面的代碼:

import generated.GetFailedLoginCount; 
import ietf.params.xml.ns.netconf.base._1.RpcType; 

public class Demo { 

    public static void main(String[] args) { 
     RpcType rpc = new RpcType(); 
     rpc.setMessageId("123"); 
     GetFailedLoginCount rpcOperation = new GetFailedLoginCount(); 
     rpc.setRpcOperation(rpcOperation); 
    } 
} 

編輯#2

改變進口導入到http://www.iana.org/assignments/xml-registry/schema/netconf.xsd我看到了相同的行爲,你先請。

要正確設置屬性,你需要做的是這樣的:

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); 

的JAXBElement爲GetFailedLoginCount值提供元素名稱。這是必需的,因爲對應rpcOperation屬性的元素替代:

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

在你的模式,它的進口netconf.xsd你應該有類型的元素「得到失敗的登錄數」,它可以取代「rpcOperation」。這將作爲QName提供給JAXBElement。因爲我們使用的元素名稱爲「foo」架構更新上面看起來像:

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

是有辦法做到#1的XSD?對於#2,它看起來像你有所有3個選項相同... – wuntee 2010-08-25 21:25:40

+0

我已經更新了我的答案,包括一個例子。 – 2010-08-26 16:00:05

+0

我還在我的博客上發佈了一個示例,其中消息對象具有Object類型的屬性,並利用@XmlAnyElement註釋來整理有效內容:http://bdoughan.blogspot.com/2010/08/using-xmlanyelement -to-build-generic.html – 2010-08-26 18:52:34

0

好了,所以這裏是什麼,我試圖做一個子集。上面的例子是非常有益的,但我依然沒能創造的JAXBElement:

基地信封,可以發現:http://www.iana.org/assignments/xml-registry/schema/netconf.xsd

有效載荷rpcOperationType(我加了**行):

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:dmi="http://xml.juniper.net/dmi" 
** xmlns:netconf="urn:ietf:params:xml:ns:netconf:base:1.0" 
> 
**<xs:import schemaLocation="netconf.xsd" namespace="urn:ietf:params:xml:ns:netconf:base:1.0"/> 
<!-- get-failed-login-count --> 
<xs:complexType name="get-failed-login-count"> 
**<xs:complexContent> 
** <xs:extension base="netconf:rpcOperationType"> 
    <xs:annotation> 
    <xs:appinfo> 
     <dmi:rpc-info> 
     <name>Get failed login count for Authentication failure and Exceeded user</name> 
     <description> 
      This command returns the Number of Logins refused due to exceeding allowed limits and Auth failure (24 hour moving window) 
     </description> 
     <rpc-reply-tag>failed-login-count</rpc-reply-tag> 
     </dmi:rpc-info> 
    </xs:appinfo> 
    </xs:annotation> 
    <xs:sequence> 
    <xs:element name="reset" type="xs:boolean" minOccurs="0"> 
     <xs:annotation> 
     <xs:appinfo> 
      <dmi:param-info> 
      <name>Reset Stats</name> 
      <description> 
       This will govern the reseting of this statistics data. By default, the data is not reset. 
      </description> 
      </dmi:param-info> 
     </xs:appinfo> 
     </xs:annotation> 
    </xs:element> 
    </xs:sequence> 
** </xs:extension> 
**</xs:complexContent> 
</xs:complexType> 

現在,產生GetFailedLogin類擴展RpcOperationType,但我不知道如何設置它在RpcType對象:

RpcType rpc = new RpcType(); 
    rpc.setMessageId("123"); 
    GetFailedLoginCount rpcOperation = new GetFailedLoginCount(); 
    rpc.setRpcOperation(); // Expects JAXBElement<? Extends RpcOperationType> 
+0

這是一個問題或答案? – skaffman 2010-09-01 18:08:04

+0

問題......最後一行'rpc.setRpcOperation();'需要傳遞給它的東西......是否有可能的rpcOperation對象鍵入JAXBElement <?擴展RpcOperationType>? – wuntee 2010-09-01 21:10:21