2013-05-03 2 views
1

Структура XML Я пытаюсь разобрать это:JAXB разбора класс-оболочку, которая содержит один строковое свойство

<contentFiles> 
<contentFile> 
<fileNumbers> 
    <fileNumber>123<fileNumber> 
</fileNumbers> 
</contentFile> 
<contentFile/> 
<contentFiles> 

Как разобрать это с помощью JAXB?

Я использовал аннотации на геттерах, описанных выше, но я получаю только последний элемент в кратных файлах FileNumbers. Я хочу сохранить все элементы FileNumbers в списке. Как мне это сделать ?

EDIT :::

@XmlRootElement(name = "contentFiles") 
public class RtSuperQuickMetadata 
{ 
    private List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems; 

    @XmlElement(name = "contentFile") 
    public final List<RtSuperQuickMetadataItem> getRtSuperQuickMetadataItems() 
    { 
     return rtSuperQuickMetadataItems; 
    } 
// Setter 
} 


public class RtSuperQuickMetadataItem 
{ 


private List<FileNumber> fileNumbers; 
public RtSuperQuickMetadataItem() 
{ 
    fileNumbers = new ArrayList<FileNumber>(); 
} 

@XmlElement(name = "fileNumbers") 
public List<FileNumber> getFileNumbers() 
{ 
    return fileNumbers; 
} 
//setter 
} 


@XmlRootElement(name="fileNumber") 
public class FileNumber 
{ 
    private String fileNumber; 

    /** 
    * Default no-arg constructor. 
    */ 
    public FileNumber() 
    { 
     // public no-arg constructor for JAXB 
    } 

    /** 
    * Accept a filenumber as constructor arg. 
    * @param fileNumber is the fileNumber 
    */ 
    public FileNumber(final String fileNumber) 
    { 
     this.fileNumber = fileNumber; 
    } 

    /** 
    * Getter. 
    * @return the fileNumber 
    */ 
    //@XmlElement(name = "fileNumber") 
    public final String getFileNumber() 
    { 
     return fileNumber; 
    } 

    /** 
    * Setter. 
    * @param fileNumber to be set. 
    */ 
    public final void setFileNumber(final String fileNumber) 
    { 
     this.fileNumber = fileNumber; 
    } 

    @Override 
    public final String toString() 
    { 
     return fileNumber; 
    } 
} 
+0

Можете ли вы показать ошибочный код? Код, который получает только последний элемент? Лучше всего будет [sscce] (http://sscce.org). –

+0

Done that .. ... – Phoenix

+0

Одна из проблем, которые я вижу, заключается в том, что у вас есть имя класса FileNumber, у которого есть такое же имя элемента, как и свойство, fileNumber, и что вашему файлу JAXB необходимо будет вложить эти два элемента. –

ответ

1

Причина, по которой я прошу представить более крупное представление XML-файла, заключается в том, что ваш код полностью зависит от требований XML-файла. Например, этот бит кода работает со следующим файлом XML:

Код:

import java.util.ArrayList; 
import java.util.List; 

import javax.xml.bind.annotation.*; 
import javax.xml.bind.*; 

public class JaxbTest { 

    private static final String RESOURCE_NAME = "data.txt"; 

    public static void main(String[] args) { 
     // marshallTest(); 

     unmarshallTest(); 
    } 

    private static void unmarshallTest() { 
     JAXBContext context; 
     try { 
     context = JAXBContext.newInstance(RtSuperQuickMetadata.class); 
     Unmarshaller unmarshaller = context.createUnmarshaller(); 
     RtSuperQuickMetadata metaData = (RtSuperQuickMetadata) unmarshaller 
       .unmarshal(JaxbTest.class.getResourceAsStream(RESOURCE_NAME)); 
     System.out.println(metaData); 
     } catch (JAXBException e) { 
     e.printStackTrace(); 
     } 
    } 

    private static void marshallTest() { 
     RtSuperQuickMetadata data = new RtSuperQuickMetadata(); 
     List<RtSuperQuickMetadataItem> metaItemList = new ArrayList<RtSuperQuickMetadataItem>(); 
     RtSuperQuickMetadataItem metaDataItem = new RtSuperQuickMetadataItem(); 
     List<FileNumber> fileNumbers = new ArrayList<FileNumber>(); 
     fileNumbers.add(new FileNumber("123")); 
     fileNumbers.add(new FileNumber("124")); 
     fileNumbers.add(new FileNumber("125")); 
     fileNumbers.add(new FileNumber("126")); 
     metaDataItem.setFileNumbers(fileNumbers); 
     metaItemList.add(metaDataItem); 
     data.setRtSuperQuickMetadataItems(metaItemList); 
     JAXBContext context; 
     try { 
     context = JAXBContext.newInstance(RtSuperQuickMetadata.class); 
     Marshaller marshaller = context.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     marshaller.marshal(data, System.out); 

     } catch (JAXBException e) { 
     e.printStackTrace(); 
     } 
    } 
} 

@XmlRootElement(name = "contentFiles") 
class RtSuperQuickMetadata { 
    private List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems; 

    @XmlElement(name = "contentFile") 
    public final List<RtSuperQuickMetadataItem> getRtSuperQuickMetadataItems() { 
     return rtSuperQuickMetadataItems; 
    } 

    public void setRtSuperQuickMetadataItems(
     List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems) { 
     this.rtSuperQuickMetadataItems = rtSuperQuickMetadataItems; 
    } 

    @Override 
    public String toString() { 
     return "RtSuperQuickMetadata [rtSuperQuickMetadataItems=" 
      + rtSuperQuickMetadataItems + "]"; 
    } 

} 

class RtSuperQuickMetadataItem { 

    private List<FileNumber> fileNumbers; 

    public RtSuperQuickMetadataItem() { 
     fileNumbers = new ArrayList<FileNumber>(); 
    } 

    @XmlElement(name = "fileNumbers") 
    public List<FileNumber> getFileNumbers() { 
     return fileNumbers; 
    } 

    public void setFileNumbers(List<FileNumber> fileNumbers) { 
     this.fileNumbers = fileNumbers; 
    } 

    @Override 
    public String toString() { 
     return "RtSuperQuickMetadataItem [fileNumbers=" + fileNumbers + "]"; 
    } 

} 

@XmlRootElement(name = "fileNumber") 
class FileNumber { 
    private String fileNumber; 

    public FileNumber() {} 

    public FileNumber(final String fileNumber) { 
     this.fileNumber = fileNumber; 
    } 

    // @XmlElement(name = "fileNumber") 
    public final String getFileNumber() { 
     return fileNumber; 
    } 

    public final void setFileNumber(final String fileNumber) { 
     this.fileNumber = fileNumber; 
    } 

    @Override 
    public final String toString() { 
     return fileNumber; 
    } 
} 

файл XML, предполагая, что он находится в том же каталоге, что и ваши файлы классов: jaxbTest.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<contentFiles> 
    <contentFile> 
     <fileNumbers> 
      <fileNumber>123</fileNumber> 
     </fileNumbers> 
     <fileNumbers> 
      <fileNumber>124</fileNumber> 
     </fileNumbers> 
     <fileNumbers> 
      <fileNumber>125</fileNumber> 
     </fileNumbers> 
     <fileNumbers> 
      <fileNumber>126</fileNumber> 
     </fileNumbers> 
    </contentFile> 
</contentFiles> 

Однако, если это не ваша желаемая структура XML, код должен измениться.


Редактировать
Если вы хотите, чтобы не гнездятся каждый элемент Номер_файла в элементе fileNumbers, а затем избавиться от класса FileNumbers и вместо того, чтобы использовать List<String> с @XmlElementWrapper аннотацию.

@XmlElementWrapper(name = "fileNumbers") 
@XmlElement(name = "fileNumber") 
public List<String> getFileNumbers() { 
    return fileNumbers; 
} 

Например, пожалуйста, проверьте этот код:

import java.util.ArrayList; 
import java.util.List; 

import javax.xml.bind.annotation.*; 
import javax.xml.bind.*; 

public class JaxbTest { 

    private static final String RESOURCE_NAME = "data.xml"; 

    public static void main(String[] args) { 
     // marshallTest(); 
     unmarshallTest(); 
    } 

    private static void unmarshallTest() { 
     JAXBContext context; 
     try { 
     context = JAXBContext.newInstance(RtSuperQuickMetadata.class); 
     Unmarshaller unmarshaller = context.createUnmarshaller(); 
     RtSuperQuickMetadata metaData = (RtSuperQuickMetadata) unmarshaller 
       .unmarshal(JaxbTest.class.getResourceAsStream(RESOURCE_NAME)); 
     System.out.println(metaData); 
     } catch (JAXBException e) { 
     e.printStackTrace(); 
     } 
    } 

    private static void marshallTest() { 
     RtSuperQuickMetadata data = new RtSuperQuickMetadata(); 
     List<RtSuperQuickMetadataItem> metaItemList = new ArrayList<RtSuperQuickMetadataItem>(); 
     RtSuperQuickMetadataItem metaDataItem = new RtSuperQuickMetadataItem(); 
     // List<FileNumber> fileNumbers = new ArrayList<FileNumber>(); 
     // fileNumbers.add(new FileNumber("123")); 
     // fileNumbers.add(new FileNumber("124")); 
     // fileNumbers.add(new FileNumber("125")); 
     // fileNumbers.add(new FileNumber("126")); 

     List<String> fileNumbers = new ArrayList<String>(); 
     fileNumbers.add("123"); 
     fileNumbers.add("124"); 
     fileNumbers.add("125"); 
     fileNumbers.add("126"); 

     metaDataItem.setFileNumbers(fileNumbers); 
     metaItemList.add(metaDataItem); 
     data.setRtSuperQuickMetadataItems(metaItemList); 
     JAXBContext context; 
     try { 
     context = JAXBContext.newInstance(RtSuperQuickMetadata.class); 
     Marshaller marshaller = context.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     marshaller.marshal(data, System.out); 

     } catch (JAXBException e) { 
     e.printStackTrace(); 
     } 
    } 
} 

@XmlRootElement(name = "contentFiles") 
class RtSuperQuickMetadata { 
    private List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems; 

    @XmlElement(name = "contentFile") 
    public final List<RtSuperQuickMetadataItem> getRtSuperQuickMetadataItems() { 
     return rtSuperQuickMetadataItems; 
    } 

    public void setRtSuperQuickMetadataItems(
     List<RtSuperQuickMetadataItem> rtSuperQuickMetadataItems) { 
     this.rtSuperQuickMetadataItems = rtSuperQuickMetadataItems; 
    } 

    @Override 
    public String toString() { 
     return "RtSuperQuickMetadata [rtSuperQuickMetadataItems=" 
      + rtSuperQuickMetadataItems + "]"; 
    } 

} 

class RtSuperQuickMetadataItem { 

    private List<String> fileNumbers; 

    public RtSuperQuickMetadataItem() { 
     fileNumbers = new ArrayList<String>(); 
    } 

    @XmlElementWrapper(name = "fileNumbers") 
    @XmlElement(name = "fileNumber") 
    public List<String> getFileNumbers() { 
     return fileNumbers; 
    } 

    public void setFileNumbers(List<String> fileNumbers) { 
     this.fileNumbers = fileNumbers; 
    } 

    @Override 
    public String toString() { 
     return "RtSuperQuickMetadataItem [fileNumbers=" + fileNumbers + "]"; 
    } 

} 

будет работать с этим XML:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<contentFiles> 
    <contentFile> 
     <fileNumbers> 
      <fileNumber>123</fileNumber> 
      <fileNumber>124</fileNumber> 
      <fileNumber>125</fileNumber> 
      <fileNumber>126</fileNumber> 
     </fileNumbers> 
    </contentFile> 
</contentFiles> 
+0

У него нет нескольких тегов fileNumbers. Просто умножится на fileNumber, вложенный в один файлNumbers – Phoenix

+0

. Затем избавиться от класса FileNumbers - используйте «Список » –

+0

@Phoenix: см. Редактирование моего ответа, и в частности мое использование аннотации '@ XmlElementWrapper'. –

0

Это было время, так как я сделал JAX-B, но я думаю, что это следует сделать трюк (только соответствующие разделы размещены). Если вы хотите избежать создания класса FileNumberList, вы, вероятно, можете сделать это с помощью адаптера, но это будет больше работы, чем того стоит.

public class RtSuperQuickMetadataItem { 

    @XmlElement 
    public FileNumberList getFileNumbers() { 

    } 

} 

public class FileNumberList { 

    @XmlElement(name="fileNumber") 
    public List<String> getList() { 

    } 

} 
+1

Чтобы избежать создания класса FileNumberList, просто используйте аннотацию XmlElementWrapper; пользовательский адаптер не нужен. –