2011-05-12 43 views
6

我想反序列化XML像在Java中使用JAXB如下:內部文本和子元素

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
    <container> 
     inner text that I need 
     <foo attrib="meh"> 
      <bar>value</bar> 
     </foo> 
    </container> 
</root> 

被絆倒我是捕獲的<container>內文本的事情:我不能同時使用一個@XmlValue來獲取內部文本和@XmlElement來抓取內部文本之後的foo元素。見下文對我所期待的大綱做

import java.io.ByteArrayInputStream; 
import java.io.UnsupportedEncodingException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.XmlValue; 
import javax.xml.stream.XMLEventReader; 
import javax.xml.stream.XMLInputFactory; 
import javax.xml.stream.XMLStreamException; 
import javax.xml.stream.events.XMLEvent; 

public class App { 

    private static final String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root><container>text<foo attrib=\"meh\"><bar>waffles</bar></foo></container></root>"; 

    @XmlRootElement(name = "foo") static class Foo { 
     @XmlAttribute public String attrib; 
     @XmlElement public String bar; 
    } 

    @XmlRootElement(name = "container") static class Container { 
     //@XmlValue public String innerText; 
     @XmlElement public Foo foo; 
    } 

    public static void main(String[] args) { 
     try { 
      final XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); 
      final XMLEventReader xer = xmlInputFactory.createXMLEventReader(new ByteArrayInputStream(xml.getBytes("UTF-8"))); 

      XMLEvent evt = xer.nextEvent(); // start document 
      evt = xer.nextEvent(); // <root> 
      evt = xer.peek(); // advance to <container> 

      JAXBContext ctx = JAXBContext.newInstance(Container.class); 
      Unmarshaller um = ctx.createUnmarshaller(); 
      Object o = um.unmarshal(xer); 
     } catch (UnsupportedEncodingException ex) { 
      Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (XMLStreamException ex) { 
      Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex); 
     } catch (JAXBException ex) { 
      Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

回答

4

這就是所謂的「混合模式的內容」,而它通常是在屁股過程中的疼痛。

JAXB中的關鍵是使用@XmlMixed註釋 - 請參閱javadoc

嘗試這樣:

@XmlRootElement(name = "container") 
static class Container { 
    @XmlMixed 
    @XmlElementRefs({ 
      @XmlElementRef(name="foo", type=Foo.class) 
    }) 
    List<?> content; 

    // ... plus the usual getters/setters 
} 

content列表應包含Foo對象和字符串的序列。

+1

我明白了這一點,我添加了一些訪問器類如 public String getInnerText(){ for(Object o:this.content){ if(o instanceof String)return o.toString(); } return null; (對象o:this.content){ } if(o instanceof Foo)return(Foo)o; } return null; } 謝謝! – rhollencamp 2011-05-12 18:09:45