3

是否可以仅使用该属性的名称将属性/元素值设置为 JAXB 对象?

例子:

如果我有课

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

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

  // setters and getters
}

我可以在不使用 setter( 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")
4

2 回答 2

1

注意: 我是EclipseLink JAXB (MOXy)负责人,也是JAXB (JSR-222)专家组的成员。

按属性名称设置值

您可以使用java.lang.reflectAPI 为您的对象设置一个值。

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 设置值

MOXy 提供了通过 XPath 在域对象中获取/设置值的能力。下面是一个例子。

演示

在下面的示例中,我们需要深入挖掘底层 MOXy 实现以访问该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.properties

要将 MOXy 用作您的 JAXB 提供程序,您需要jaxb.properties使用以下条目添加一个在与域模型相同的包中调用的文件(请参阅:http ://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as -你的.html):

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
于 2012-12-19T12:49:28.797 回答
0

最好的方法是在其设置器上提供它们。

如果你的方法

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

为你做二传手工作。那么它也是正确的

于 2012-12-19T12:28:11.977 回答