java - 在 Xerces 中从 DOM 获取 XML 实体替换文本

标签 java xml dom entities xerces

org.w3c.dom.Entity 的 Javadoc状态:

XML does not mandate that a non-validating XML processor read and process entity declarations made in the external subset or declared in parameter entities. This means that parsed entities declared in the external subset need not be expanded by some classes of applications, and that the replacement text of the entity may not be available. When the replacement text is available, the corresponding Entity node's child list represents the structure of that replacement value. Otherwise, the child list is empty.

虽然它不引用内部子集中的实体声明,但肯定有一些解析器配置可以读取和处理任一子集中的实体声明?事实上,我对文档的阅读表明这是默认设置。

无论如何,我已经针对已在内部子集(如图所示)和外部子集中声明的实体测试了以下方法(使用 Xerces),但是 foo.hasChildNodes() 在每种情况下都返回 false(并且 foo.getChildNodes() 返回 foo!):

// some trivial example XML
String xml = "<!DOCTYPE example [ <!ENTITY foo 'bar'> ]>\n<example/>";
InputStream is = new ByteArrayInputStream(xml.getBytes());

// parse
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
DocumentType docType = builder.parse(is).getDoctype();

// retrieve the entity - works fine
Entity foo = (Entity) docType.getEntities().getNamedItem("foo");

// now how to get the entity's replacement text?

毫无疑问,我遗漏了一些相当明显的东西;感谢您的想法。


编辑

从目前的答案来看,我的 Xerces 实现似乎有问题。我将尝试将所有 Xerces 库更新到最新版本,如果这解决了我的问题,我将关闭该问题。非常感谢。


更新

更新Xerces确实解决了问题,前提是实体是从文档中引用的;如果不是,则该节点仍然没有子节点。我不完全清楚为什么会这样。如果有人能解释发生了什么和/或告诉我如何强制创建子节点而无需明确引用文档中的每个实体,我将不胜感激。

最佳答案

我认为您可能误解了替换文本的工作原理。根据一些阅读 (http://www.javacommerce.com/displaypage.jsp?name=entities.sql&id=18238),在我看来替换文本就像一个变量。因此,在上面的示例中,您永远不会引用 &foo; 实体。如果您运行下面的代码示例,您将看到 &foo; 被替换为字符串 bar:

// some trivial example XML
String xml = "<!DOCTYPE example [ <!ENTITY foo 'bar'> ]><example><foo>&foo;</foo></example>";
InputStream is = new ByteArrayInputStream(xml.getBytes());

// parse
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(is);
DocumentType docType = doc.getDoctype();

// retrieve the entity - works fine
Entity foo = (Entity) docType.getEntities().getNamedItem("foo");
for(int i = 0; i < foo.getChildNodes().getLength(); i++) {
  System.out.println(foo.getChildNodes().item(i));
}

您看到打印的是 [#text: bar],这是 XML 中的文本替换。

关于java - 在 Xerces 中从 DOM 获取 XML 实体替换文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6115972/

相关文章:

events - jQuery 更改事件未从键盘触发?

javascript - 如何更改 JS 中的字体大小以适合其容器?

java - Java JPA 一对多关系的问题

java - 使用JAVA和UNIX运行Pig命令

excel - VBA XML : Find root nodes for multiple namespaces

java - GWT 中的 XML 解析

java - 如何将 Chartboost 依赖项添加到我的 LibGDX 项目?

java - 无法在 java 中从 String 转换为 float

java - Android Java,为什么我的按钮使我的应用程序崩溃

javascript - 文档.body.style.color = 'blue' ; document.body.style.fontSize = 18px';不适用于 Android WebKit