2013-08-01 171 views
1

我現在面臨使用JAXB XML一個問題。 我希望能夠產生這樣的XML文件:定義XML元素具有相同名稱的

<Animals> 
<Animal type="A"> 
    <name>aaaa</name> 
    <j>text1</j> 
</Animal> 
<Animal type="A"> 
    <name>bbbb</name> 
    <j>text3</j> 
</Animal> 
<Animal type="A"> 
    <name>cccc</name> 
    <j>text5</j> 
</Animal> 
<Animal type="B"> 
    <name>vvvvv</name> 
    <i>3</i> 
</Animal> 
<Animal type="B"> 
    <name>ffff</name> 
    <i>4</i> 
</Animal> 
<Animal type="B"> 
    <name>zzzz</name> 
    <i>7</i> 
</Animal> 

這兩種類型的有一些相似的元素,而其它的尤其如此。例如,需要j和不能爲空,如果類型=「A」,且i是必需的並且不能爲空,如果類型=「B」。這可能嗎?

這裏是動物類:

@XmlRootElement(name = "Animals") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Animals { 
@XmlElement(name="Animal") 
private List<AnimalA> listA; 
@XmlElement(name="Animal") 
private List<AnimalB> listB; 
//Getters and Setters 
... 
//Constructors 
... 

} 測試它,這裏是一個主要功能:

public static void main(String[] args) { 
    System.out.println("Starting here..."); 
    AnimalA a = new AnimalA("animalA", "valueA"); 
    AnimalB b = new AnimalB("animalB", "valueb",3); 
    AnimalB b2 = new AnimalB("animalB2", "valueb2",56); 
    List<AnimalA> listA = new ArrayList<AnimalA>(); 
    List<AnimalB> listB = new ArrayList<AnimalB>(); 
    listA.add(a); 
    listB.add(b); 
    listB.add(b2); 
    Animals animals = new Animals(listA,listB); 

    JAXBContext context = null; 

    try { 
     context = JAXBContext.newInstance(Animals.class); 

     Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     if (animals != null) { 
      m.marshal(animals, new File("C:\\animalz.xml")); 
     } 
    } catch (JAXBException e) { 
     System.out.println(e); 
    } 

    Animals aa = null; 
    URL url = null; 
     try { 

      url = new File("C:\\animalz.xml").toURI().toURL(); 
      Unmarshaller unmarshaller = context.createUnmarshaller(); 
      aa = (Animals) unmarshaller.unmarshal(url); 
      int countA = aa.getListA().size(); 
        //    int countB = aa.getListB().size(); 
      System.out.println("size A==>"+countA); 
        //    System.out.println("size B ==>"+countB); 
     } catch (JAXBException e) { 
      System.out.println(e.getMessage());; 
     } catch (MalformedURLException e) { 
      System.out.println(e.getMessage());; 
     } 
} 

這將返回: 這裏開始...... 尺寸A ==> 3 如果我取消CountB的線,它得到一個NullPointerException。

回答

0

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

你可以使用莫西的@XmlPath擴展該用例:

動物

import java.util.List; 
import javax.xml.bind.annotation.*;  
import org.eclipse.persistence.oxm.annotations.XmlPath; 

@XmlRootElement(name="Animals") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class Animals { 


    @XmlPath("Animal[@type='A']") 
    private List<AnimalA> listA; 

    @XmlPath("Animal[@type='B']") 
    private List<AnimalB> listB; 

} 

演示

標準JAXB運行時API用於將XML轉換到/自對象。

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

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

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("input.xml"); 
     Animals animals = (Animals) unmarshaller.unmarshal(xml); 

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

} 

input.xml中/輸出

<?xml version="1.0" encoding="UTF-8"?> 
<Animals> 
    <Animal type="A"> 
     <name>aaaa</name> 
     <j>text1</j> 
    </Animal> 
    <Animal type="A"> 
     <name>bbbb</name> 
     <j>text3</j> 
    </Animal> 
    <Animal type="A"> 
     <name>cccc</name> 
     <j>text5</j> 
    </Animal> 
    <Animal type="B"> 
     <name>vvvvv</name> 
     <i>3</i> 
    </Animal> 
    <Animal type="B"> 
     <name>ffff</name> 
     <i>4</i> 
    </Animal> 
    <Animal type="B"> 
     <name>zzzz</name> 
     <i>7</i> 
    </Animal> 
</Animals> 

更多信息

+0

是它工作的感謝,但沒有@XmlElement(NAME =「動物」),這意味着在XML文件中使用的標籤和listA的數組listB。我如何重命名他們? – callafa

+0

@callafa - 要獲得'@ XmlPath'註釋工作,你需要使用莫西爲您的JAXB提供商。以下是一個可運行示例的鏈接:https:// github。com/bdoughan/blog20110322 –

+0

它的工作原理,但我不能改變標籤的名稱。 – callafa

0

認爲你在找什麼是一樣的東西:

public class Animal { 
    @XmlAttribute("type") 
    private String type; 

    @XmlElement(name="j", required=false) 
    private String j; 

    @XmlElement(name="i", required=false) 
    private String i; 

我不知道任何方式爲您強制執行A​​類總是有第j元素。如果你需要那種程度的驗證,我想你會需要一個更惱人的結構:

<Animal_A> 
    <j>asdf</j> 
</Animal_A> 
<Animal_B> 
    <i>asdf</i> 
</Animal_B> 
相關問題