首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Java中解析包含HTML实体的XML文件而不更改XML

在Java中解析包含HTML实体的XML文件而不更改XML
EN

Stack Overflow用户
提问于 2016-03-16 11:36:36
回答 5查看 12.2K关注 0票数 21

我必须用Java语言解析一大堆XML文件,这些文件有时包含—>等HTML实体,但这些实体是无效的。我知道处理这个问题的正确方法是在解析之前向XML文件添加适当的实体声明。但是,我不能这样做,因为我无法控制这些XML文件。

是否存在某种我可以覆盖的回调,以便在Java XML解析器遇到这样的实体时被调用?我在API中找不到。

我想使用:

代码语言:javascript
复制
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

DocumentBuilder parser = dbf.newDocumentBuilder();
Document        doc    = parser.parse( stream );

我发现我可以在org.xml.sax.helpers.DefaultHandler中覆盖resolveEntity,但是如何在更高级别的API中使用它呢?

下面是一个完整的示例:

代码语言:javascript
复制
public class Main {
    public static void main( String [] args ) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder parser = dbf.newDocumentBuilder();
        Document        doc    = parser.parse( new FileInputStream( "test.xml" ));
    }

}

使用test.xml:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <bar>Some&nbsp;text &mdash; invalid!</bar>
</foo>

产生:

代码语言:javascript
复制
[Fatal Error] :3:20: The entity "nbsp" was referenced, but not declared.
Exception in thread "main" org.xml.sax.SAXParseException; lineNumber: 3; columnNumber: 20; The entity "nbsp" was referenced, but not declared.

更新:我一直在用调试器查看JDK源代码,天哪,真是太麻烦了。我不知道那里有什么设计,或者是否有一个。一层洋葱能叠加多少层?

它们的关键类似乎是com.sun.org.apache.xerces.internal.impl.XMLEntityManager,但我找不到任何代码,可以让我在使用它之前向它添加东西,或者尝试在不通过那个类的情况下解析实体。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2016-03-24 01:52:15

为此,我会使用像Jsoup这样的库。我在下面测试了一下,它是有效的。我不知道这有没有帮助。它可以在这里找到:http://jsoup.org/download

代码语言:javascript
复制
public static void main(String args[]){


    String html = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><foo>" + 
                  "<bar>Some&nbsp;text &mdash; invalid!</bar></foo>";
    Document doc = Jsoup.parse(html, "", Parser.xmlParser());

    for (Element e : doc.select("bar")) {
        System.out.println(e);
    }   


}

结果:

代码语言:javascript
复制
<bar>
 Some&nbsp;text — invalid!
</bar>

从文件加载可以在以下位置找到:

http://jsoup.org/cookbook/input/load-document-from-file

票数 11
EN

Stack Overflow用户

发布于 2016-03-24 01:18:32

另一种方法,因为您并没有使用严格的OXM方法。您可能想尝试使用不太严格的解析器,比如JSoup?这将立即停止无效XML模式等问题,但它只会将问题转移到您的代码中。

票数 3
EN

Stack Overflow用户

发布于 2016-03-19 03:08:32

只是为了给解决方案添加一种不同的方法:

您可以使用流实现封装您的输入流,该实现将实体替换为合法的实体。

虽然这肯定是一个技巧,但它应该是一个快速而简单的解决方案(或者更好地说:变通)。

不过,没有xml框架内部解决方案那么优雅和干净。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36026353

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档