2010-11-16 4 views
2

Я обновляемом объект Java, который в настоящее время имеет представление XML в этом духе:аннотирования добавление атрибута к элементу

<myObjects> 
    <myObject uid="42" type="someEnum"> 
     <name>Waldo</name> 
     <description>yada yada</description> 
     <myElement>some_string</myElement> 
     ... 
    </myObject> 
    ... 
</myObjects> 

MyElement не является обязательным - это может быть пустым в Java/опущено XML.
Я добавляю поле, которое только значение, если MyElement имеет фактическое значение (и сохранить совместимость с предыдущей XML, это необязательно сам по себе)

Я пытаюсь избежать этого:

<myElement>some_string</myElement> 
    <myAttr>foo</myAttr> 

и предпочитают что-то вроде этого:

<myElement myAttr="foo">some_string</myElement> 

но стучал головой в течение 2 дней не w о том, как его аннотировать.

  • Я думал пометив его с XmlTransient и досадный XmlAnyElement поймать это вместо того, чтобы в то время как немаршалинг - но мне кажется, это вызовет проблемы, когда сортировочная объект обратно из Java в XML.
  • Я попытался создать для элемента XmlAdapter, но метод unmarshal получает только внутренний контент («some_string»). Я что-то пропустил с помощью этой техники?
  • Есть ли способ просто получить элемент в виде строки ("< MyElement myAttr = \ "Foo \" > some_string </MyElement >"), и я буду процесс это сам?
  • Вы рекомендуете какой-либо другой подход?
+0

Нам нужно увидеть ваш java – skaffman

+0

Если это было непонятно - мне нужно только поддерживать совместимость с предыдущими файлами XML. И я могу делать все, что захочу, с помощью Java-кода. Поэтому я намеренно не поставлял его, чтобы не уклоняться от вас (Блейз Доуэн общался с ним довольно хорошо). – targumon

ответ

3

Вы можете использовать расширение на EclipseLink JAXB (MOXy) @XmlPath легко сделать это:

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlRootElement; 

import org.eclipse.persistence.oxm.annotations.XmlPath; 

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

    @XmlAttribute 
    private int uid; 

    @XmlAttribute 
    private String type; 

    private String name; 

    private String description; 

    private String myElement; 

    @XmlPath("myElement/@myAttr") 
    private String myAttr; 

} 

Этот класс будет взаимодействовать со следующим XML:

<myObject uid="42" type="someEnum"> 
    <name>Waldo</name> 
    <description>yada yada</description> 
    <myElement myAttr="foo">some_string</myElement> 
</myObject> 

Используя следующий демонстрационный код:

import java.io.File; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 

public class Demo { 

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

     File file = new File("input.xml"); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     MyObject myObject = (MyObject) unmarshaller.unmarshal(file); 

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

} 

Чтобы указать MOXy как реализацию JAXB, вам необходимо включить файл jaxb.свойства в том же пакете, как классы моделей с помощью следующей записи:

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

Для получения дополнительной информации о XPath Moxy, основанное отображение см:

+0

В конце концов я не использовал ваше решение (см. Ниже мой собственный ответ). Но я многому научился от вашего объяснения и вашего блога, поэтому я отметил его как «принятый» :-) – targumon

1

Ответ был мертв просто: я так привык к аннотации с XmlElement и XmlAttribute, что я забыл про XmlValue!

Код для MyObject такая же, как и в Блез Doughan ответ, с одним изменением: MyElement теперь класс (ElemWithAttr) вместо строки:

public class ElemWithAttr { 
    @XmlValue 
    public String content; 

    @XmlAttribute 
    public String myAttr; 
} 
Смежные вопросы