java - 使用 Woodstox 解析 XML 时保持实体不变
问题描述
我正在使用 Woodstox 处理>
在其中一个节点的值中包含一些实体(最明显的是 )的 XML。举一个极端的例子,它是这样的:
<parent> < > & " ' </parent>
我已经为WstxInputFactory ( IS_REPLACING_ENTITY_REFERENCES
, P_TREAT_CHAR_REFS_AS_ENTS
, P_CUSTOM_INTERNAL_ENTITIES
...) 和WstxOutputFactory尝试了很多不同的配置选项,但无论我尝试什么,输出始终是这样的:
<parent>nbsp; < nbsp; > & " ' nbsp;</parent>
(>
被转换为>
,<
保持不变,
失去&
......)
我正在使用创建的XMLEventReader读取 XML
XMLEventReader reader = wstxInputFactory.createXMLEventReader(new StringReader(fulltext));
配置WstxInputFactory之后。
有没有办法将 Woodstox 配置为忽略所有实体并完全按照输入字符串中的内容输出文本?
解决方案
将始终处理基本的五个 XML 实体(quot、amp、apos、lt、gt)。据我所知,没有办法通过 Sax 获得它们的来源。
对于其他实体,您可以手动处理它们。您可以捕获事件直到元素结束并连接值:
XMLInputFactory factory = WstxInputFactory.newInstance();
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, Boolean.FALSE);
XMLEventReader xmlr = factory.createXMLEventReader(
this.getClass().getResourceAsStream(xmlFileName));
String value = "";
while (xmlr.hasNext()) {
XMLEvent event = xmlr.nextEvent();
if (event.isCharacters()) {
value += event.asCharacters().getData();
}
if (event.isEntityReference()) {
value += "&" + ((EntityReference) event).getName() + ";";
}
if (event.isEndElement()) {
// Assign it to the right variable
System.out.println(value);
value = "";
}
}
对于您的示例输入:
<parent> < > & " ' </parent>
输出将是:
< > & " '
否则,如果您想转换所有实体,也许您可以为未声明的实体使用自定义XmlResolver:
public class NaiveHtmlEntityResolver implements XMLResolver {
private static final Map<String, String> ENTITIES = new HashMap<>();
static {
ENTITIES.put("nbsp", " ");
ENTITIES.put("apos", "'");
ENTITIES.put("quot", "\"");
// and so on
}
@Override
public Object resolveEntity(String publicID,
String systemID,
String baseURI,
String namespace) throws XMLStreamException {
if (publicID == null && systemID == null) {
return ENTITIES.get(namespace);
}
return null;
}
}
然后告诉 Woodstox 将其用于未声明的实体:
factory.setProperty(WstxInputProperties.P_UNDECLARED_ENTITY_RESOLVER, new NaiveHtmlEntityResolver());
推荐阅读
- python - 在没有主目录名称的情况下启动 os.walk
- progress-bar - Inno Setup:如何处理 [UninstallDelete] 部分的进度条?
- sql - 选择包含其他列的列,SQL
- mongodb - 如何在 MongoDB 4.0 上创建副本集
- javascript - 根据选定的单选按钮将两个字段显示为必填字段
- jquery - event.preventDefault(); 无法在 ajax post laravel Framework 5.8.17 中工作
- c# - .NET Core 但不是 .NET Framework 的 400 BadRequest 响应
- javascript - 在下面的所有 div 上使用 css 模糊效果
- beagleboneblack - 在 BeagleBone Black 上读取、加载和卸载驱动程序的命令?
- php - PHP:来自 ZipArchive::statIndex() 的 CRC 是否足够独特,可用于检测许多 zip 中的重复文件?