JAXB混合内容列表包含换行符

时间:2014-03-09 15:45:25

标签: java xml jaxb

我希望你能帮助我解决我在JAXB面临的问题。

我有以下XML文件:

<root>
    <prop>
        <field1>
            <value1>v1</value1>
            <value2>v2</value2>
        </field1>
        <field2>
            <value1>v1</value1>
            <value2>v2</value2>
        </field2>
    </prop>
    <prop>
        text
        <field1>
            <value1>v1</value1>
            <value2>v2</value2>
        </field1>
    </prop>
    <prop>
        text
    </prop>
</root>

XML可以支持其他元素(field1,field2),文本或两者。

以下课程:

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

    protected List<Root.Element> prop;

    @XmlAccessorType(XmlAccessType.FIELD)
    public static class Element {
        @XmlMixed
        protected List<String> content;
        @XmlElement
        public Field1 field1;
        @XmlElement
        public Field2 field2;

        @XmlAccessorType(XmlAccessType.FIELD)
        public static class Field1 {
            @XmlElement
            protected String value1;
            @XmlElement
            protected String value2;
        }

        @XmlAccessorType(XmlAccessType.FIELD)
        public static class Field2 {
            @XmlElement
            protected String value1;
            @XmlElement
            protected String value2;

        }

    }

}

我想将XML解组到上面的类中。 我遇到的问题是,除了文本之外,我在内容列表中获得了其他字符,如换行符和制表符。更具体地说,基于上面的XML,当我尝试解组时,我得到:

  • 第一道具有内容,如[“\ n \ t \ t”,“\ n \ t \ t”,“\ n \ t”] - 它应该 是一个空列表
  • 第二道具,内容如[“\ n \ t \ ttext \ n \ t \ t”, “\ n \ t”] - 它应该是一个包含一个字符串的列表
  • 内容第三道具 喜欢[“\ n \ t \ ttext \ n \ t”] - 它应该是一个空列表

我已经尝试创建和XMLAdapter,但它适用于列表中的每个元素,所以如果我删除\ n和\ t并返回null如果它是一个空字符串我仍然得到一个包含一些字符串的列表和一些空值。

1 个答案:

答案 0 :(得分:5)

为什么会发生

具有混合上下文的元素中的空白内容被视为重要内容。

如何修复

您可以将JAXB与StAX一起使用来支持此用例。使用StAX,您可以创建过滤的XMLStreamReader,以便任何仅包含空格的字符串不会报告为事件。以下是如何实现它的示例。

import javax.xml.bind.*;
import javax.xml.stream.*;
import javax.xml.transform.stream.StreamSource;

public class Demo {

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

        XMLInputFactory xif = XMLInputFactory.newFactory();
        XMLStreamReader xsr = xif.createXMLStreamReader(new StreamSource("src/forum22284324/input.xml"));
        xsr = xif.createFilteredReader(xsr, new StreamFilter() {

            @Override
            public boolean accept(XMLStreamReader reader) {
                if(reader.getEventType() == XMLStreamReader.CHARACTERS) {
                    return reader.getText().trim().length() > 0;
                } 
                return true;
            }

        });

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Root root = (Root) unmarshaller.unmarshal(xsr);
    }

}