我正在解析(很多)包含我事先不知道的实体引用的 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.
有什么建议吗?当然,我已经很乐意用空字符串替换未知实体。
谢谢,
最佳答案
StAX API 对此提供支持。看看XMLInputFactory , 它有一个 runtime property这决定了内部实体是扩展还是保留在原地。如果设置为 false
,则 StAX 事件流将包含 EntityReference
的实例以表示未展开的实体。
如果你仍然想要一个 DOM 作为最终结果,你可以像这样将它链接在一起:
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
inputFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
String xml = "my xml";
StringReader xmlReader = new StringReader(xml);
XMLEventReader eventReader = inputFactory.createXMLEventReader(xmlReader);
StAXSource source = new StAXSource(eventReader);
DOMResult result = new DOMResult();
transformer.transform(source, result);
Node document = result.getNode();
在这种情况下,生成的 DOM 将包含与文本节点混合的 org.w3c.dom.EntityReference
节点。然后,您可以根据需要处理这些内容。
关于java - 如何处理未知实体引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2434072/