设置仅提供xml属性/元素名称的对象值

时间:2012-12-19 12:23:40

标签: java jaxb

是否可以仅使用该属性的名称将属性/元素值设置为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")

2 个答案:

答案 0 :(得分: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设置值

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-your.html):

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

答案 1 :(得分:0)

最好的方法是通过其制定者提供它们。

如果你的方法

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

为你做setter工作。那么它也是正确的