是否有任何 Java HTML 解析器在其中生成的节点保留原始文本的索引?
Posted
技术标签:
【中文标题】是否有任何 Java HTML 解析器在其中生成的节点保留原始文本的索引?【英文标题】:Are there any Java HTML parsers where the generated Nodes retain indexes to the original text? 【发布时间】:2011-11-09 22:01:29 【问题描述】:我想以 XML 格式查询 html 文档(例如使用 XPath),所以我需要通过某种形式的 HTML 清理器来传递 HTML。
但我还想根据查询结果对原始源字符串进行修改。
是否有一个 Java HTML 解析器保留原始源字符串的索引,以便我可以找到一个节点并修改原始字符串的正确部分?
干杯。
【问题讨论】:
使用 DOM,然后将其转换为字符串表示不是更好吗?随着您的更改,您将拥有更简洁的 HTML 版本。是否有特定原因需要修改原始源字符串? 我能想到一个。如果您不必费力地处理一堆文本更改,这些更改只是由于解解析器呈现 XML 的方式略有不同,那么您可以更轻松地找出进行了哪些实质性修改。 Vivin - 我正在尝试从 HTML 页面中“清除”某些敏感项目,以便我可以针对原始 HTML 运行其他解析测试(敏感数据被 999 或 xxx 等覆盖)。另外,我希望不同的测试能够在 Java 和 javascript 中运行,因此原始源代码对我来说是最好的起点,因为 Java HTML 解析器和每个浏览器的 HTML 解析器可能会导致不同的 DOM(即使它们可能应该't)。 【参考方案1】:您可以尝试使用ANTLR 和HTML grammar。
您可以采用(至少)两种方法 - 尝试将其用作实际的 HTML 解析器,然后将索引放入您感兴趣的原始字符串中。
或者,它还具有对源文本进行就地转换的内置支持,您可以在其中定义要对文本执行的转换作为语法的一部分。
【讨论】:
【参考方案2】:我们使用jericho html parser 进行解析,使用htmlcleaner 进行实际清理。
我们修复了 jericho 在服务器应用(内存管理、日志记录)中的行为问题。 (最初的开发者认为我们的问题不够重要,不能放在主代码分支中)。 Our fork is on github. 我们还制作了fixes to htmlcleaner。
【讨论】:
【参考方案3】:这很好用
http://jtidy.sourceforge.net/
示例
Tidy tidy = new Tidy(); // obtain a new Tidy instance
tidy.setXHTML(boolean xhtml); // set desired config options using tidy setters
... // (equivalent to command line options)
tidy.parse(inputStream, System.out);
对于 DOM 爬取,我推荐使用 JDOM,它比简单的 XML 更快。
http://www.jdom.org/
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.newDocument();
Element root = doc.createElement("root");
Text text = doc.createText("This is the root");
root.appendChild(text);
doc.appendChild(root);
就实现而言,我会制作一个新文档,并从源代码中添加节点。
【讨论】:
【参考方案4】:听起来 Jericho 几乎正是您想要的。它是一个强大的 HTML 解析器,专为对源文档进行非侵入式修改而设计。
虽然它不附带 DOM、SAX 或 StAX 接口,但它具有与那些标准足够相似的自定义 API,您应该能够相当轻松地调整您的方法以适应它们,或者在任何您需要的东西之间编写适配器正在使用和耶利哥。例如,您可以使用 Jaxen 对 Jericho 文档进行 XPath 查询——例如,请参阅 this blog entry。
Jericho 对每个元素都有begin 和 end 属性,甚至对于元素的某些部分,例如标签名称甚至属性名称,因此您可以使用该信息自己编辑文档,但 Jericho 真正闪耀的地方是OutputDocument 类,它允许您通过调用与查询匹配的 Jericho 元素的适当方法直接指定替换,而不必显式调用它们的 getBegin() 和 getEnd() 并将其传递给某个替换方法。
【讨论】:
我也会检查一下。谢谢。当我尝试过它们时,我会回来回答每个问题。【参考方案5】:正如其他人所建议的,您可能想要渲染 DOM。这基本上只是意味着构建节点树,除非您使用像 jTidy 这样的 HTML 清理器,否则它不会改变文档源。然后,您可以轻松访问文档并根据需要进行修改。我建议DOM4J,它也有很好的 api 和 xpath 支持。
关于您的“索引”要求,在您遍历/查询文档期间,您可以在列表中缓存或映射您希望稍后修改其文本的任何元素或节点。
【讨论】:
【参考方案6】:我猜你可以使用HTML Parser。
您可以使用Node 类中的getStartPosition() 和getEndPosition() 获取原始Page 的索引。
【讨论】:
会检查并通知您。【参考方案7】:我不知道“保留原始文本的索引”部分,但Jericho 是一个非常好的 HTML 解析器库。
这是一个如何从 html 中删除每个 span 的示例:
public static String removeSpans(String html)
Source source = new Source(html);
source.fullSequentialParse();
OutputDocument outputDocument = new OutputDocument(source);
List<Tag> tags = source.getAllTags();
for (Tag tag : tags)
String tagname = tag.getName().toLowerCase();
if (tagname.equals("span"))
//remove the <span>
outputDocument.remove(tag);
return outputDocument.toString();
【讨论】:
很抱歉投了反对票,但这个答案与我的问题无关。以上是关于是否有任何 Java HTML 解析器在其中生成的节点保留原始文本的索引?的主要内容,如果未能解决你的问题,请参考以下文章
流式处理和基于树的 XML 解析器在 JAVA 开始时是不是消耗相似数量的内存
使用 DOM 解析器在 Java 中解析具有 2 个默认命名空间的 XML
如何让 C 语言中的 ANTLR3.5 生成的解析器在 MVS EBCDIC 环境中工作?
jQuery 选择器在从 ajax 解析的 HTML 中的行为不符合预期