XPath和XQuery可以处理HTML文档吗?

问题描述 投票:2回答:5

我听说HTML文档不是https://stackoverflow.com/a/39560454的XML文档。

XPath和XQuery处理XML文档。他们可以处理HTML文档,为什么?

虽然我不知道为什么,但我猜XPath可以用于HTML文档,因为https://www.quora.com/Why-do-we-use-XPath-in-Selenium-even-though-CSS-Selector-is-fasterhttps://html-agility-pack.net/

html xml web xpath xquery
5个回答
6
投票

XQuery和XPath被定义为处理称为XDM的特定数据模型。在XPath 1.0中,这在XPath规范中描述;在XQuery和更高版本的XPath版本中,它在单独的规范中定义。 XPath和XQuery可以处理定义了XDM映射的任何数据。 XML和HTML DOM在XDM的许多细节上都有所不同,但是可以(有点实用主义)定义到XDM的映射,因此可以使XPath针对XML和HTML DOM运行。实际上,这两种映射都被广泛使用,即使它们不完美且在某些情况下效率低下。

HTML映射到XDM的最大问题是命名空间;传统上,XPath实现将诸如“table”和“p”之类的HTML元素视为没有名称空间,因此可以使用诸如//table//p之类的路径,而不使用名称空间前缀。但是在HTML5中,WhatWG决定这些元素在XHTML命名空间中,这意味着他们必须定义XPath规范的变体以适应这些路径。

CSS选择器已经慢慢获得了XPath 1.0的大部分表现力,尽管它们肯定不像以后的版本那么丰富,并且因为它们主要是为HTML而不是XML而设计的,所以它们有时可以更方便地使用。我没有看到任何性能数据,但是浏览器厂商必须花费大量精力来快速制作CSS,并且他们似乎在过去的15年中对他们的XPath实现几乎没有开发,所以它肯定不会如果CSS在大多数浏览器中更快,我会感到惊讶。 DOM和XDM之间的差异也会产生开销:特别是DOM中命名空间的低效表示。


2
投票

HTML不保证格式良好,因此XML解析器可能无法解析它(除非您使用非常有限的HTML子集)。但是,XHTML是HTML的良好表现,据我所知,在具有相同功能集的浏览器中工作(参见:https://www.w3.org/TR/html-polyglot/)。

但是,如果您已经拥有HTML,那么您需要将其转换为XML以使用XPath / XQuery。 “HTML tidy”有各种实现,可以选择输出应该有效的有效XML。您的XQuery处理器可能提供某种形式的整洁。如果没有,有许多语言和独立实现可能会让你到那里。


2
投票

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文档上工作吗?”,这表明他们可以,并且他们只能处理器无关的规范 - 这里需要注意的是,不同的实现可能会以不同的方式解释规范。


1
投票

事实上,Xpath可用于对付html文档。这样做的包/模块/应用程序的一些示例

  • 硒司机
  • python上的lxml(基于libxml2)
  • bash上的xmllint(基于libxml2)

1
投票

当我想在HTML文档上使用XPath(比XPath 1.0更新)时,我写了一个完整的XQuery interpreter for HTML

除了标准的XQuery 3.0之外,我还添加了一些可选的扩展(实际上不允许,但对HTML很有用),例如匹配节点名称不区分大小写或者使用名称空间更轻松。

© www.soinside.com 2019 - 2024. All rights reserved.