在JAXB中处理非格式良好的(数字)元素标记

时间:2013-02-12 20:47:40

标签: java xml xsd jaxb

我正在尝试将JAXB用于技术上不符合XML标准的数据;特别是,元素的名称在技术上是无效的,因为它们以数字字符开头。以下是模式的概述。

<xs:element name = "ITEM">
    <xs:complexType>
        <xs:sequence>
            <xs:element name="01" />
            <xs:element name="08" />
            <xs:element name="10">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="10_A" />
                        <xs:element name="10_B" />
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            ...
            ...Many more elements...
            ...
        </xs:sequence>
    </xs:complexType>
</xs:element>

不幸的是,我没有能力修改它。由于完整的ITEM非常庞大且具有多个深度,因此使用像JAXB这样的自动化工具来创建类是必须的。为此,我使用字符(在本例中为'm')为元素的名称添加前缀,以便XJC接受它。我希望在运行时,我可以将XML标记映射到我的Java类,以便将输入解组为Java对象。特别是这样的事情:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "m01",
    "m08",
    "m10",
    ...
})
@XmlRootElement(name = "ITEM")
public class ITEM {
    @XmlElement(name = "01")
    protected String m01;
    @XmlElement(name = "08")
    protected String m08;
    @XmlElement(name = "10")
    protected M10 m10;
    ...
}

M10看起来像:

@XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "m10a",
        "m10b",
        ...
})
public static class M10 {
    @XmlElement(name = "10_A")
    protected String m10a;
    @XmlElement(name = "10_B")
    protected String m10b;
    ...
}

我希望JAXB能够将@XmlElement标记与输入中的标记相匹配,但不幸的是,这对我来说并不适用,因为JAXB不会使用不正确的标记进行任何此类业务。如果有人感兴趣,特殊例外是:

org.xml.sax.SAXParseException: The content of elements must consist of well-formed character data or markup

有人对如何解决这个问题有任何建议吗?我觉得在JAXB解析它之前我可能会对输入XML运行正则表达式交换(从而完全绕过这个问题),但是以这种方式修改输入是不可取的。

2 个答案:

答案 0 :(得分:2)

这不是JAXB(JSR-222)实现的抱怨,而是使用的底层解析器。诀窍是找到一个宽容的XML解析器。

<强> StAX的

如果您能找到能够处理此内容的StAX(JSR-173)解析器,那么您可以执行以下操作:

import java.io.StringReader;
import javax.xml.bind.*;
import javax.xml.stream.*;

public class Demo {

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

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        StringReader xml = new StringReader("<ITEM><01>Hello World</01></ITEM");
        XMLStreamReader xsr = XMLInputFactory.newFactory().createXMLStreamReader(xml);
        ITEM item = (ITEM) unmarshaller.unmarshal(xsr);
    }

}

<强> SAX

或者,如果您找到SAX解析器,则可以执行以下操作:

import java.io.StringReader;
import javax.xml.bind.*;
import javax.xml.parsers.*;
import org.xml.sax.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        SAXParserFactory spf = SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        XMLReader xr = sp.getXMLReader();

        JAXBContext jc = JAXBContext.newInstance(ITEM.class);
        UnmarshallerHandler unmarshallerHandler = jc.createUnmarshaller().getUnmarshallerHandler();
        xr.setContentHandler(unmarshallerHandler);

        StringReader xml = new StringReader("<ITEM><01>Hello World</01></ITEM");
        InputSource inputSource = new InputSource(xml);
        xr.parse(inputSource);

        ITEM item = (ITEM) unmarshallerHandler.getResult();
    }

}

答案 1 :(得分:1)

这不是“技术上无效的XML”。它根本不是XML。没有办法处理遵循某些XML规则但不遵循其他规则的东西 - 除了找到一个可以转换成适当XML的XML修复工具。