java如何处理未知的实体引用?
我正在解析(很多)包含实体引用的XML文件,这些实体引用我事先不知道(不能改变这个事实)
例如:
xml = "<tag>I'm content with &funny; &entity; &references;.</tag>"
当我尝试使用以下代码解析此代码时:
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final DocumentBuilder db = dbf.newDocumentBuilder();
final InputSource is = new InputSource(new StringReader(xml));
final Document d = db.parse(is);
我得到以下例外情况:
org.xml.sax.SAXParseException: The entity "funny" was referenced, but not declared.
但是,我想要实现的是,解析器用空字符串“”替换每个未声明(解析器未知)的实体。 或者更好,是否有一种方法可以将映射传递给解析器,如:
Map<String,String> entityMapping = ...
entityMapping.put("funny","very");
entityMapping.put("entity","important");
entityMapping.put("references","stuff");
这样我就可以做到以下几点:
final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final DocumentBuilder db = dbf.newDocumentBuilder();
final InputSource is = new InputSource(new StringReader(xml));
db.setEntityResolver(entityMapping);
final Document d = db.parse(is);
如果我使用此示例代码从文档中获取文本,我将收到:
I'm content with very important stuff.
有什么建议吗?当然,我已经很乐意用空字符串替换未知实体
谢谢
# 1 楼答案
StAX API支持这一点。看看XMLInputFactory,它有一个runtime property,它决定内部实体是被扩展,还是留在原地。如果设置为
false
,则StAX事件流将包含EntityReference
的实例,以表示未展开的实体如果您仍然想要一个DOM作为最终结果,可以像这样将其链接在一起:
在这种情况下,生成的DOM将包含
org.w3c.dom.EntityReference
的节点与文本节点混合。然后,您可以根据自己的需要处理这些问题# 2 楼答案
可以在文件的开头添加实体。查看更多信息
您还可以看看this thread,其中似乎有人实现了EntityResolver接口(您也可以实现EntityResolver!)您可以在其中动态处理实体(例如,使用建议的地图)
WARNING: there is a bug!在jdk6中,但您可以在jdk5中尝试
# 3 楼答案
既然XML输入似乎可以作为字符串使用,那么就不能用正则表达式替换进行简单的预处理吗
这是一个非常复杂的过程,您可能需要花费一些额外的精力来确保regexp只匹配它们真正应该匹配的地方(想想^{),但至少它是
当然,有比多次调用
replaceAll()
更有效的方法来实现相同的效果