当文档以 lower-case <!doctype 开头时,空手道 HTML 解析抛出 SaxException
Karate HTML parsing throwing SaxException when document begins with lower-case <!doctype
我正在尝试 运行 一个在 URL 上调用 GET 的空手道测试,但我发现当网站 returns 它的 <!doctype
声明在小写(在 'normal' HTML 中完全可以接受),我认为空手道 XML 解析器会抛出致命错误和警告。在我看来,空手道使用 XML 解析器,所以严格来说,这可能是正确的行为,因为小写 doctype
会中断。但是,对于有效 HTML,我找不到解决此问题的方法。我玩过不同的 headers 等等,但似乎无法通过这个。
我已经包含了一个小测试,幸运的是 google.com returns 小写声明也是:
示例测试
Given url 'http://www.google.com'
When method GET
Then status 200
错误
[Fatal Error] :1:3: The markup in the document preceding the root element must be well-formed.
15:19:45.267 [main] WARN com.intuit.karate.FileUtils - parsing failed: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 3; The markup in the document preceding the root element must be well-formed.
<!doctype html><html .... blah
我下载了 Karate 源代码并发现报告的警告:
FileUtils.java
public static String toPrettyString(String raw) {
raw = StringUtils.trimToEmpty(raw);
try {
if (Script.isJson(raw)) {
return JsonUtils.toPrettyJsonString(JsonUtils.toJsonDoc(raw));
} else if (Script.isXml(raw)) {
return XmlUtils.toString(XmlUtils.toXmlDoc(raw), true);
}
} catch (Exception e) {
logger.warn("parsing failed: {}", e.getMessage());
}
return raw;
}
通过检查返回文档的第一个字符,检查似乎介于 JSON 或 XML 之间:
Script.java
public static final boolean isXml(String text) {
return text.startsWith("<");
}
XmlUtils.java
然后我认为 builder.parse
失败,因为它不是有效的 XHTML,因为后面的注释暗示 <!doctype
将在递归调用中被删除。
public static Document toXmlDoc(String xml) {
...
Document doc = builder.parse(is);
if (dtdEntityResolver.dtdPresent) { // DOCTYPE present
// the XML was not parsed, but I think it hangs at the root as a text node
// so conversion to string and back has the effect of discarding the DOCTYPE !
return toXmlDoc(toString(doc, false));
是否可以为有效 HTML 转移此流量?
如果您查看日志,空手道还会告诉您它已将完整响应(将在 response
变量中提供)保留为字符串 - 即使它未能 "type cast" 到 XML。顺便说一句,你甚至在 responseBytes
中有一个 byte-array。所以现在你可以做任何你想做的事了,例如,理论上你可以找到一个 "lenient" 的 HTML 解析器并得到一个 DOM 树或其他东西。
Given url 'http://www.google.com'
When method GET
Then status 200
* print response
一些提示,您可以尝试在 response
上进行字符串替换,然后尝试将其 type-cast 替换为 XML,请参考:https://github.com/intuit/karate#type-conversion
或者您可能只是想抓取一些数据,一些正常的正则表达式匹配可能会起作用,请参考这些:
我正在尝试 运行 一个在 URL 上调用 GET 的空手道测试,但我发现当网站 returns 它的 <!doctype
声明在小写(在 'normal' HTML 中完全可以接受),我认为空手道 XML 解析器会抛出致命错误和警告。在我看来,空手道使用 XML 解析器,所以严格来说,这可能是正确的行为,因为小写 doctype
会中断。但是,对于有效 HTML,我找不到解决此问题的方法。我玩过不同的 headers 等等,但似乎无法通过这个。
我已经包含了一个小测试,幸运的是 google.com returns 小写声明也是:
示例测试
Given url 'http://www.google.com'
When method GET
Then status 200
错误
[Fatal Error] :1:3: The markup in the document preceding the root element must be well-formed.
15:19:45.267 [main] WARN com.intuit.karate.FileUtils - parsing failed: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 3; The markup in the document preceding the root element must be well-formed.
<!doctype html><html .... blah
我下载了 Karate 源代码并发现报告的警告:
FileUtils.java
public static String toPrettyString(String raw) {
raw = StringUtils.trimToEmpty(raw);
try {
if (Script.isJson(raw)) {
return JsonUtils.toPrettyJsonString(JsonUtils.toJsonDoc(raw));
} else if (Script.isXml(raw)) {
return XmlUtils.toString(XmlUtils.toXmlDoc(raw), true);
}
} catch (Exception e) {
logger.warn("parsing failed: {}", e.getMessage());
}
return raw;
}
通过检查返回文档的第一个字符,检查似乎介于 JSON 或 XML 之间:
Script.java
public static final boolean isXml(String text) {
return text.startsWith("<");
}
XmlUtils.java
然后我认为 builder.parse
失败,因为它不是有效的 XHTML,因为后面的注释暗示 <!doctype
将在递归调用中被删除。
public static Document toXmlDoc(String xml) {
...
Document doc = builder.parse(is);
if (dtdEntityResolver.dtdPresent) { // DOCTYPE present
// the XML was not parsed, but I think it hangs at the root as a text node
// so conversion to string and back has the effect of discarding the DOCTYPE !
return toXmlDoc(toString(doc, false));
是否可以为有效 HTML 转移此流量?
如果您查看日志,空手道还会告诉您它已将完整响应(将在 response
变量中提供)保留为字符串 - 即使它未能 "type cast" 到 XML。顺便说一句,你甚至在 responseBytes
中有一个 byte-array。所以现在你可以做任何你想做的事了,例如,理论上你可以找到一个 "lenient" 的 HTML 解析器并得到一个 DOM 树或其他东西。
Given url 'http://www.google.com'
When method GET
Then status 200
* print response
一些提示,您可以尝试在 response
上进行字符串替换,然后尝试将其 type-cast 替换为 XML,请参考:https://github.com/intuit/karate#type-conversion
或者您可能只是想抓取一些数据,一些正常的正则表达式匹配可能会起作用,请参考这些: