我正在使用Xerces来解析我的XML文档。问题在于,像 这样的XML转义字符在characters()方法中显示为非转义字符。我需要按原样在characters()方法中获取转义字符。

谢谢。

UPD:尝试在resolveEntity()的后代中覆盖DefaultHandler方法。从调试中可以看到,它已设置为XML阅读器的实体解析器,但是未调用覆盖方法中的代码。

最佳答案

我认为您的解决方案还不错:只需几行代码即可完成您想要的事情。
问题在于startEntity接口(interface)未提供endEntityContentHandler方法,因此您必须编写与LexicalHandler结合使用的ContentHandler
通常,XMLFilter的使用更优雅,但是您必须使用实体,因此您仍然应该编写LexicalHandler。查看here,以了解SAX过滤器的用法。

我想向您展示一种与您的方法非常相似的方法,该方法使您可以将过滤操作(例如,将wrapping和&包装)与输出操作(或其他操作)分开。我已经基于XMLFilter编写了自己的XMLFilterImpl,它也实现了LexicalHandler接口(interface)。此过滤器仅包含与实体转义/转义有关的代码。

public class XMLFilterEntityImpl extends XMLFilterImpl implements
        LexicalHandler {

    private String currentEntity = null;

    public XMLFilterEntityImpl(XMLReader reader)
            throws SAXNotRecognizedException, SAXNotSupportedException {
        super(reader);
        setProperty("http://xml.org/sax/properties/lexical-handler", this);
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        if (currentEntity == null) {
            super.characters(ch, start, length);
            return;
        }

        String entity = "&" + currentEntity + ";";
        super.characters(entity.toCharArray(), 0, entity.length());
        currentEntity = null;
    }

    @Override
    public void startEntity(String name) throws SAXException {
        currentEntity = name;
    }

    @Override
    public void endEntity(String name) throws SAXException {
    }

    @Override
    public void startDTD(String name, String publicId, String systemId)
            throws SAXException {
    }

    @Override
    public void endDTD() throws SAXException {
    }

    @Override
    public void startCDATA() throws SAXException {
    }

    @Override
    public void endCDATA() throws SAXException {
    }

    @Override
    public void comment(char[] ch, int start, int length) throws SAXException {
    }
}

这是我的主要工作,使用DefaultHandler作为ContentHandler来根据过滤器代码按原样接收实体:
public static void main(String[] args) throws ParserConfigurationException,
        SAXException, IOException {

    DefaultHandler defaultHandler = new DefaultHandler() {
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            //This method receives the entity as is
            System.out.println(new String(ch, start, length));
        }
    };

    XMLFilter xmlFilter = new XMLFilterEntityImpl(XMLReaderFactory.createXMLReader());
    xmlFilter.setContentHandler(defaultHandler);
    String xml = "<html><head><title>title</title></head><body>&amp;</body></html>";
    xmlFilter.parse(new InputSource(new StringReader(xml)));
}

这是我的输出:
title
&amp;

可能您不喜欢它,无论如何这是一个替代解决方案。

很抱歉,但是使用SaxParser,我认为您没有更优雅的方式了。

您还应该考虑将切换到StaxParser :将XMLInputFactory.IS_REPLACING_ENTITY_REFERENCE设置为false可以很容易地完成您想要的操作。如果您喜欢这种解决方案,则应该看看here

关于java - SAX解析器: Ignoring special characters,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5475202/

10-11 10:53