我正在使用Xerces来解析我的XML文档。问题在于,像 
这样的XML转义字符在characters()
方法中显示为非转义字符。我需要按原样在characters()
方法中获取转义字符。
谢谢。
UPD:尝试在resolveEntity()
的后代中覆盖DefaultHandler
方法。从调试中可以看到,它已设置为XML阅读器的实体解析器,但是未调用覆盖方法中的代码。
最佳答案
我认为您的解决方案还不错:只需几行代码即可完成您想要的事情。
问题在于startEntity
接口(interface)未提供endEntity
和ContentHandler
方法,因此您必须编写与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>&</body></html>";
xmlFilter.parse(new InputSource(new StringReader(xml)));
}
这是我的输出:
title
&
可能您不喜欢它,无论如何这是一个替代解决方案。
很抱歉,但是使用
SaxParser
,我认为您没有更优雅的方式了。您还应该考虑将切换到
StaxParser
:将XMLInputFactory.IS_REPLACING_ENTITY_REFERENCE
设置为false可以很容易地完成您想要的操作。如果您喜欢这种解决方案,则应该看看here。关于java - SAX解析器: Ignoring special characters,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5475202/