微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JSoup解析属性=“值”=“”

如何解决JSoup解析属性=“值”=“”

我的用例

  1. 从网站下载 HTML 文件
  2. 用JSoup解析
  3. 使用 JSoup 将其转换为有效的 XML
  4. 使用 XPath (javax.xml.xpath) 从该 XML 文档中读取元素和属性

(这是在大多数情况下按预期实现和工作的。)

问题/原因

有一种情况会失败:

  1. 源 HTML 文件包含这样的无效内容 <div someattribute="somevalue"=""></div>
  2. JSoup 将其转换为同样无效的字符串 <div someattribute="somevalue" =""=""></div>
  3. XPath 无法解析无效的 JSoup 输出 XML。

问题和解决方法

  1. 是否可以给 JSoup 一个提示,以便它为这个无效输入产生有效的输出
  2. 是否可以给 XPath 一个提示,以便它解析无效输入(=JSoup 输出)?
  3. 是的,作为后备,我可以从 HTML 字符串中过滤掉无效的 "="" 并将其替换为 ",但是当有一个可以解析无效 HTML 的库时,为什么要自己这样做!?

技术细节

不幸的是,我想由 JSoup 解析的 HTML 文档包含类似以下代码段的内容

<div someattribute="somevalue"=""></div>

使用此配置调用 JSoup ...

Document doc = Jsoup.parse(html);
doc.outputSettings().Syntax(Document.OutputSettings.Syntax.xml).charset(StandardCharsets.UTF_8);
String html = doc.html();

... 返回包含此代码段的 HTML 文档:

<div someattribute="somevalue" =""=""></div>

XPath 然后中止解析此文档并显示以下消息:

Auf Elementtyp "div" müssen entweder Attributspezifikationen,">" oder "/>" folgen.

在英语中是这样的:

Element type "div" must be followed by either attribute specifications,">" or "/>".

解决方法

jsoup 包含一个到 W3C DOM 模型的转换器,其中包括转换时的属性过滤。然后,您可以直接在该对象上运行 xpath 查询,这不仅有效,而且比序列化为 XML 然后重新解析它更有效。

请参阅 org.jsoup.helper.W3CDom

的文档

这是一个例子:

import org.w3c.dom.Document;
import org.w3c.dom.Node;
...

String html = "<div someattribute=\"somevalue\"=\"\"></div>";
org.jsoup.nodes.Document jdoc = Jsoup.parse(html);
Document w3doc = W3CDom.convert(jdoc);

String query = "//div";
XPathExpression xpath = XPathFactory.newInstance().newXPath().compile(query);
Node div = (Node) xpath.evaluate(w3doc,XPathConstants.NODE);

System.out.printf("Tag: %s,Attribute: %s",div.getNodeName(),div.getAttributes().getNamedItem("someattribute"));

(注意这里的 DocumentNode 是 W3C DOM,而不是 jsoup DOM。)

这给了我们:

Tag: div,Attribute: someattribute="somevalue"

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。