EXPath W3C社区有一份规范,其中包含一个HTTP客户端模块,可从XPath和XQuery实现中访问,并对HTML内容进行“整理”。请参见规范的
http://expath.org/spec/http-client#d2e517部分以了解此功能的详细描述:
如果媒体类型是HTML类型,则会整理并解析内容(该过程取决于实现),其项为生成的文档节点。
现在,您可能认为将HTTP引入查询HTML的问题有些绕远路,但是人们自然希望通过HTTP检索HTML文档并对其进行查询或遍历。这符合处理器不可知的精神。
以下代码示例是标准XQuery代码,适用于任何支持EXPath HTTP Client的XPath或XQuery实现。它演示了如何检索HTML5文档(在这里为HTML5规范本身,其未关闭的标签,如
<meta>
,使其成为非格式良好的XML),并通过XPath表达式查询它:
xquery version "3.1"
declare namespace html = "http://www.w3.org/1999/xhtml"
import module namespace http = "http://expath.org/ns/http-client"
let $url := "https://www.w3.org/TR/html5/"
return
if (doc-available($url)) then
"The URL was well-formed XML. No tidying required. :)"
else
let $response := http:send-request(<http:request href="{$url}" method="GET"/>)
let $response-head := $response[1]
let $response-body := $response[2]
return
if (
$response-head/http:body/@media-type eq "text/html"
and $response-body instance of document-node()
) then
"The URL was an HTML document that was tidied into a "
|| "well-formed XML document. :) For example: "
|| $response-body//html:meta => head() => serialize()
else
"The HTTP Client wasn't able to parse the result "
|| "into a well-formed XML document. :("
这将返回:
The URL was an HTML document that was tidied into a well-formed XML document. :)
For example:
<html:meta
xmlns:html="http://www.w3.org/1999/xhtml"
http-equiv="Content-Type"
content="text/html; charset=utf-8"/>
请注意,这个
<meta>
元素是格式良好的XML,并由XPath表达式
//html:meta
生成。(我在eXist中进行了测试。相同的代码在BaseX中也可以工作,只是表达式不同
//meta
,因为BaseX不像eXist一样将整理过的HTML强制转换为HTML命名空间。)
我应该补充一点,HTTP客户端规范将“整理”留给处理器定义,因此从一个实现到另一个实现肯定会有差异,但如果问题是“XPath和XQuery是否可以用于HTML文档?”,那么这证明了它们可以,并且只能使用处理器无关的规范——但要注意不同的实现可能会以不同的方式解释规范。