2

我正在尝试将 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 之前对输入 XML 运行正则表达式交换(从而完全绕过这个问题),但是以这种方式修改输入是相当不可取的。

4

2 回答 2

2

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

斯塔克斯

如果您可以找到能够处理此内容的 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 解析器,那么您可以执行以下操作:

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();
    }

}
于 2013-02-12T21:09:06.107 回答
1

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

于 2013-02-13T13:11:54.170 回答