内部文本和子元素

rho*_*amp 6 java xml jaxb

我想在Java中使用JAXB反序列化XML,如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <container>
        inner text that I need
        <foo attrib="meh">
            <bar>value</bar>
        </foo>
    </container>
</root>
Run Code Online (Sandbox Code Playgroud)

绊倒我的是捕获内部文本<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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ska*_*man 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
}
Run Code Online (Sandbox Code Playgroud)

content列表应包含一系列Foo对象和字符串。