2012-12-19 59 views
3

是否可以僅使用該屬性的名稱將屬性/元素值設置爲JAXB對象?設置僅提供xml屬性/元素名稱的對象值

例子:

如果我有一個類

@XmlRootElement(name = "book") 
public class Book { 

    @XmlElement(name = "title") 
    private String name; 
    @XmlElement(name = "author") 
    private String author; 

    // setters and getters 
} 

我可以設置的名稱,而不使用它的Set(setName()),但只知道XML元素名稱?在這種情況下是"title"。它可能看起來像這樣:

JAXBContext context = JAXBContext.newInstance(Book.class); 
Something s = context.create***(); 
s.setValueToObject(book, "title", "New name"); // should do the same like book.setName("New name") 

回答

1

注:我是EclipseLink JAXB (MOXy)領導和JAXB (JSR-222)專家組的成員。

設定值按屬性名稱

您可以使用java.lang.reflect API來設置你的對象的值。

package forum13952415; 

import java.lang.reflect.Field; 
import javax.xml.bind.*; 

public class ReflectionDemo { 

    public static void main(String[] args) throws Exception { 
     Customer customer = new Customer(); 

     setValueToObject(customer, "firstName", "Jane"); 
     setValueToObject(customer, "lastName", "Doe"); 

     JAXBContext jc = JAXBContext.newInstance(Customer.class); 
     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(customer, System.out); 
    } 

    private static void setValueToObject(Object object, String property, Object value) throws Exception { 
     Class clazz = object.getClass(); 
     Field field = clazz.getDeclaredField(property); 
     field.setAccessible(true); 
     field.set(object, value); 
    } 

} 

設定值與XPath

莫西提供的XPath來獲取/設置值的域對象的能力。下面是一個例子。

演示

在下面的例子中,我們需要向下挖掘到潛在的莫西實現獲得訪問setValueByXPath方法。

package forum13952415; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import org.eclipse.persistence.jaxb.JAXBHelper; 
import org.eclipse.persistence.oxm.XMLContext; 

public class Demo { 

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

     XMLContext xmlContext = JAXBHelper.unwrap(jc, XMLContext.class); 

     Customer customer = new Customer(); 
     xmlContext.setValueByXPath(customer, "@id", null, 123); 
     xmlContext.setValueByXPath(customer, "first-name/text()", null, "Jane"); 
     xmlContext.setValueByXPath(customer, "last-name/text()", null, "Doe"); 

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

} 

輸出

下面是從運行演示代碼的輸出。

<?xml version="1.0" encoding="UTF-8"?> 
<customer id="123"> 
    <first-name>Jane</first-name> 
    <last-name>Doe</last-name> 
</customer> 

客戶

下面是一個示例域模型。我使用了一個XML名稱與Java名稱不同的名稱。

package forum13952415; 

import javax.xml.bind.annotation.*; 

@XmlRootElement 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Customer { 

    @XmlAttribute(name="id") 
    private int primaryKey; 

    @XmlElement(name="first-name") 
    private String firstName; 

    @XmlElement(name="last-name") 
    private String lastName; 

} 

jaxb。性能

要使用莫西爲您的JAXB提供者,你需要添加一個名爲jaxb.properties文件在同一個包中的以下項您的域模型(見:http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html):

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 
+0

在您的'reflect'例如,'setValueToObject'的參數'property'是該字段的名稱。但是,從註釋中獲取屬性名稱會很有用。但不要打擾,因爲我知道該怎麼做。我只是想知道是否有一種方法可以使用JAXB庫。我想它內部有一個方法,當它讀取xml輸入時正好使用。 –

0

最好的方法是通過它的setter提供它們。

如果你的方法

s.setValueToObject(book, "title", "New name"); // should do the same like book.setName("New name") 

爲你做的setter工作。那麼它也是正確的

+0

這方法不存在。我在問圖書館是否實施了類似的東西。否則,我可以在課堂上搜索註釋,並用反思去做。但我不想重新發明輪子。 –

+0

沒有沒有類似的東西 –

+0

JLinkB的EclipseLink MOXy實現(JSR-222)提供了@TrueSoft正在尋找的'setValueByXPath'方法:http://stackoverflow.com/a/13952834/383861 –