当我需要 DocumentBuilder 时使用 SAX 解析器

Posted

技术标签:

【中文标题】当我需要 DocumentBuilder 时使用 SAX 解析器【英文标题】:Using a SAX parser when I need a DocumentBuilder 【发布时间】:2014-05-01 00:10:08 【问题描述】:

XMLBeam 是一个不错的 XML 到 POJO 解组器(通过 XPath),但它只允许您配置 DocumentBuilder 或 DocumentBuilderFactory。

TagSoup 是一个不错的 SAX 解析器,它可以让您像解析 XML 一样解析讨厌的 html 文档。

我想使用 TagSoup 作为 XMLBeam 的 XML 解析器,这样我就可以使用 XPath 将讨厌的 HTML 解组为 POJO。

有没有办法转换或包装 SAX 解析器,以便我可以将其用作 DocumentBuilder 或 DocumentBuilderFactory?

【问题讨论】:

【参考方案1】:

您可以将 SAX 包装在 DocumentBuilder 中。 XMLBeam 只使用了 DocumentBuilder 的 parse(InputSource) 方法,所以非常简单:

import org.ccil.cowan.tagsoup.Parser;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.xml.sax.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.sax.SAXSource;
import java.io.IOException;

public class MyDocumentBuilder extends DocumentBuilder 

    @Override
    public Document parse(InputSource inputSource) throws SAXException, IOException 

        XMLReader xmlReader = new Parser();
        xmlReader.setFeature(Parser.namespacesFeature, false);
        xmlReader.setFeature(Parser.namespacePrefixesFeature, false);

        try
            Transformer transformer = TransformerFactory.newInstance().newTransformer();
            DOMResult domResult = new DOMResult();
            transformer.transform(new SAXSource(xmlReader, inputSource), domResult);
            return (Document) domResult.getNode();
        
        catch(Exception exp)
            throw new RuntimeException("Error parsing with Tagsoup");
        
    

    @Override
    public void setErrorHandler(ErrorHandler errorHandler) 

    

    @Override
    public Document newDocument() 
        return null;
    

    @Override
    public void setEntityResolver(EntityResolver entityResolver) 

    

    @Override
    public boolean isValidating() 
        return false;
    

    @Override
    public DOMImplementation getDOMImplementation() 
        return null;
    

    @Override
    public boolean isNamespaceAware() 
        return false;
    

然后,您可以在其他地方告诉 XMLBeam 使用您的 DocumentBuilder:

    XMLFactoriesConfig xmlFactoriesConfig = new DefaultXMLFactoriesConfig()
        @Override
        public DocumentBuilder createDocumentBuilder() 
            return new MyDocumentBuilder();
        
    ;

    XBProjector xbProjector = new XBProjector(xmlFactoriesConfig);

【讨论】:

以上是关于当我需要 DocumentBuilder 时使用 SAX 解析器的主要内容,如果未能解决你的问题,请参考以下文章

DocumentBuilder.parse 是不是关闭 InputStream

如何在 Java DocumentBuilder 中解析 XSD 文件期间将元素附加到现有节点列表

xml(3)

Java——DOM方式生成XML (转)

Java解析XML三种常用方法

读入 XML 到文件 Java