Я борюсь с разбором JAXB и нуждаюсь в некотором руководстве.
По сути, я пытаюсь добавить атрибуты к своим переменным класса, которые я уже объявил как элементы, используя @XmlElement. До сих пор любая попытка использовать @XmlAttribute устанавливает атрибут на уровне класса.
В настоящее время я получаю следующее:
<DataClass newAttribute="test">
<myElement>I wish this element had an attribute</myElement>
<anotherElement>I wish this element had an attribute too</anotherElement>
</DataClass>
Я хотел бы сделать это:
<DataClass>
<myElement thisAtt="this is what I'm talking about">This is better</myElement>
<anotherElement thisAtt="a different attribute here">So is this</anotherElement>
</DataClass>
Я видел другие сообщения, добавляющие атрибут к одному элементу, используя @XmlValue, но это не работает, когда у вас есть элементы, и не будет работать с несколькими элементами.
У кого-нибудь есть мысли о том, как это можно реализовать?
Спасибо! Джейсон
Ответ 1 · рейтинг 6 · Ryan Stewart
Это создаст этот XML:
public class JaxbAttributes {
public static void main(String[] args) throws Exception {
Marshaller marshaller =
JAXBContext.newInstance(DataClass.class).createMarshaller();
StringWriter stringWriter = new StringWriter();
DataClass dataClass = new DataClass(
new Foo("this is what I'm talking about", "This is better"),
new Foo("a different attribute here", "So is this"));
marshaller.marshal(dataClass, stringWriter);
System.out.println(stringWriter);
}
@XmlRootElement(name = "DataClass")
@XmlType(propOrder = {"myElement", "anotherElement"})
static class DataClass {
private Foo myElement;
private Foo anotherElement;
DataClass() {}
public DataClass(Foo myElement, Foo anotherElement) {
this.myElement = myElement;
this.anotherElement = anotherElement;
}
public Foo getMyElement() { return myElement; }
public void setMyElement(Foo myElement) { this.myElement = myElement; }
public Foo getAnotherElement() { return anotherElement; }
public void setAnotherElement(Foo anotherElement) { this.anotherElement = anotherElement; }
}
static class Foo {
private String thisAtt;
private String value;
Foo() {}
public Foo(String thisAtt, String value) {
this.thisAtt = thisAtt;
this.value = value;
}
@XmlAttribute
public String getThisAtt() { return thisAtt; }
public void setThisAtt(String thisAtt) { this.thisAtt = thisAtt; }
@XmlValue
public String getValue() { return value; }
public void setValue(String value) { this.value = value; }
}
}
Ответ 2 · рейтинг 3 · bdoughan
Примечание. Я руководитель EclipseLink JAXB (MOXy). и член экспертной группы JAXB 2.X (JSR-222). .
В качестве альтернативы вы можете использовать расширение @XmlPath в MOXy для обработки этого варианта использования:
Класс данных
Аннотацию @XmlPath можно использовать со стандартными аннотациями JAXB:
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement(name="DataClass")
@XmlType(propOrder={"myElement", "anotherElement"})
public class DataClass {
private String myElement;
private String myElementThisAtt;
private String anotherElement;
private String anotherElementThisAtt;
public String getMyElement() {
return myElement;
}
public void setMyElement(String myElement) {
this.myElement = myElement;
}
@XmlPath("myElement/@thisAtt")
public String getMyElementThisAtt() {
return myElementThisAtt;
}
public void setMyElementThisAtt(String myElementThisAtt) {
this.myElementThisAtt = myElementThisAtt;
}
public String getAnotherElement() {
return anotherElement;
}
public void setAnotherElement(String anotherElement) {
this.anotherElement = anotherElement;
}
@XmlPath("anotherElement/@thisAtt")
public String getAnotherElementThisAtt() {
return anotherElementThisAtt;
}
public void setAnotherElementThisAtt(String anotherElementThisAtt) {
this.anotherElementThisAtt = anotherElementThisAtt;
}
}
Демо
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(DataClass.class);
DataClass dataClass = new DataClass();
dataClass.setMyElement("This is better");
dataClass.setMyElementThisAtt("this is what I'm talking about");
dataClass.setAnotherElement("So is this");
dataClass.setAnotherElementThisAtt("a different attribute here");
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(dataClass, System.out);
}
}
Вывод
<?xml version="1.0" encoding="UTF-8"?>
<DataClass>
<myElement thisAtt="this is what I'm talking about">This is better</myElement>
<anotherElement thisAtt="a different attribute here">So is this</anotherElement>
</DataClass>
Дополнительная информация