解析使用JAXB无效的XML - 可以解析器宽松些?(parsing invalid xml us

2019-09-19 12:33发布

我一直在使用JAXB,而现在来解析XML看起来大致是这样的:

<report>    <-- corresponds to a "wrapper" object that holds 
                some properties and two lists - a list of A's and list of B's
    <some tags with> general <info/>
    ...
    <A>   <-- corresponds to an "A" object with some properties
        <some tags with> info related to the <A> tag <bla/>
        ...
    <A/>
    <B>   <-- corresponds to an "B" object with some properties
        <some tags with> info related to the <B> tag <bla/>
        ...
    </B>
</report>

负责编组XML的一侧是可怕的,但在我的掌握。
它经常发送无效的XML字符和/或畸形XML。
我跟负责一边,得到了很多固定的错误,但有些他们似乎无法修复。
我希望我的解析器尽可能forgiveful这些错误,当它是不可能的,要得到与错误的XML尽可能多的信息成为可能。
因此,如果XML包含100 A和一个有一个问题,我还是希望能够保留其他99。
这是我最常见的问题:

1. Some info tag inner value contains invalid chars
    <bla> invalid chars here, either control chars or just &>< </bla>
2. The root entity is missing a closing tag
    <report> ..... stuff here .... NO </report> at the end!
3. An inner entity (A/B)  is missing it's closing tag, or it's somehow malformed.
    <A> ...stuff here... <somethingMalformed_blabla_A/>
    OR
    <A> ...  Something malformed here...</A>

我希望我解释自己很好。
我真的想从这些XML的尽可能多的信息越好,即使他们有问题。
我想我需要采用使用STAX /萨克斯与JAXB一起一些策略,但我不知道怎么样。
如果100 A的,一个是有一个xml的问题,我不介意扔只是A.
虽然这会更好,如果我能得到一个物体可能被解析到错误尽可能多的数据。

Answer 1:

这个答案真的帮了我:

JAXB -解组XML异常

就我而言,我解析从与XML开关(-x)Sysinternals的自动运行工具的结果。 或者是因为结果被写入到文件共享或在较新版本的一些越野车的原因,XML将畸形。 由于这种自动运行捕捉恶意软件调查的关键,我真的想要的数据。 另外,我可以从结果几乎完整的文件大小告诉。

在链接的问题解决方案的工作真的很好,当你有很多子元素的文档由OP的建议。 特别地,自动运行XML输出是很简单的,并且由许多“项”,每个包括与文本(如由XJC产生即字符串属性)一个许多简单元件。 所以,如果几个项目在年底错过了,没什么大不了的......当然,除非是涉及到恶意软件的东西。 :)

这里是我的代码:

public class Loader {

    private List<Exception> exceptions = new ArrayList<>();

    public synchronized List<Exception> getExceptions() {
        return new ArrayList<>(exceptions);
    }

    protected void setExceptions(List<Exception> exceptions) {
        this.exceptions = exceptions;
    }

    public synchronized Autoruns load(File file, boolean attemptRecovery)
      throws LoaderException {
        Unmarshaller unmarshaller;
        try {
            JAXBContext context = newInstance(Autoruns.class);
            unmarshaller = context.createUnmarshaller();
        } catch (JAXBException ex) {
            throw new LoaderException("Could not create unmarshaller.", ex);
        }
        try {
            return (Autoruns) unmarshaller.unmarshal(file);
        } catch (JAXBException ex) {
            if (!attemptRecovery) {
                throw new LoaderException(ex.getMessage(), ex);
            }
        }
        exceptions.clear();
        Autoruns autoruns = new Autoruns();
        XMLInputFactory inputFactory = XMLInputFactory.newInstance();
        try {
            XMLEventReader eventReader = 
              inputFactory.createXMLEventReader(new FileInputStream(file));
            while (eventReader.hasNext()) {
                XMLEvent event = eventReader.peek();
                if (event.isStartElement()) {
                    StartElement start = event.asStartElement();
                    if (start.getName().getLocalPart().equals("item")) {
                         // note the try should allow processing of elements
                         // after this item in the event it is malformed
                         try {
                            JAXBElement<Autoruns.Item> jax_b = 
                              unmarshaller.unmarshal(eventReader,
                                                     Autoruns.Item.class);
                            autoruns.getItem().add(jax_b.getValue());
                        } catch (JAXBException ex) {
                            exceptions.add(ex);
                        }
                    }
                }
                eventReader.next();
            }
        } catch (XMLStreamException | FileNotFoundException ex) {
            exceptions.add(ex);
        }
        return autoruns;
    }

    public static Autoruns load(Path path) throws JAXBException {
        return load(path.toFile());
    }

    public static Autoruns load(File file) throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(Autoruns.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        return (Autoruns) unmarshaller.unmarshal(file);
    }

    public static class LoaderException extends Exception {

        public LoaderException(String message) {
            super(message);
        }

        public LoaderException(String message, Throwable cause) {
            super(message, cause);
        }
    }
}


Answer 2:

XML的哲学是XML的创造者是负责创建格式良好的XML,收件人不负责抵达修复的坏的XML。 XML解析器必须拒绝病态的XML。 还有其他的“整洁”的工具,也许能坏的XML转换成XML好,但根据输入的缺陷的性质,它是不可预测的,他们将如何工作。 如果你想获得使用XML进行数据交换的好处,它需要很好地形成。 否则,你还不如使用自己的专有格式。



文章来源: parsing invalid xml using jaxb - can the parser be more lenient?
标签: xml parsing jaxb