如何在命令行中使用带有Saxon-HE的XPath解析HTML?

时间:2015-01-07 13:04:09

标签: java xml xpath xquery saxon

我使用的是saxon HE 9.6,它非常适合在解析格式良好的XML文件时使用XPath 3。

但我想知道如何将expath-http-client(或任何其他工作解决方案)与Saxon结合起来,以便能够解析realLife©®™(可能已损坏)的HTML。 (Java不是我更好的技能)。

我搜索谷歌很长时间没有任何有效的解决方案。我试过像:

xquery_file.xsl:

xquery version "1.0";

declare namespace http="http://expath.org/ns/http-client";

let $url := 'http://stackoverflow.com'
let $response := http:send-request(
   <http:request href="{$url}" method="get"/>
) return
    <echo-results>
        {$response}
    </echo-results>

Shell命令来自expath-http-client-saxon-0.10.0

的自述文件
saxon --repo /usr/share/java/expath/repo -xsl:sample/simple-get.xsl -it:main

saxon --repo /usr/share/java/expath/repo -xsl:xquery_file.xsl -it:main

没有成功。我得到:Transformation failed: Unknown configuration property http://saxon.sf.net/feature/repo

理想情况下,我最后要做的是直接从命令行查询一个URL,而不是XQuery文件,而是一个XPath表达式(如果可能的话)。我很确定一些XML / Java / XPath大师周围有我正在寻找的解决方案。

/usr/share/java/expath/repo包含:

/usr/share/java/expath/repo
├── expath-http-client-saxon-0.10.0
│   ├── cxan.xml
│   ├── expath-http-client-saxon
│   │   ├── jar
│   │   │   ├── expath-http-client-java.jar
│   │   │   └── expath-http-client-saxon.jar
│   │   ├── lib
│   │   │   ├── apache-mime4j-0.6.jar
│   │   │   ├── commons-codec-1.4.jar
│   │   │   ├── commons-logging-1.1.1.jar
│   │   │   ├── httpclient-4.0.1.jar
│   │   │   ├── httpcore-4.0.1.jar
│   │   │   └── tagsoup-1.2.jar
│   │   ├── xq
│   │   │   └── expath-http-client-saxon.xq
│   │   └── xsl
│   │       └── expath-http-client-saxon.xsl
│   ├── expath-pkg.xml
│   └── saxon.xml
└── hello-1.1
    ├── expath-pkg.xml
    └── hello
        ├── hello.xq
        └── hello.xsl

编辑:

我最好的尝试(基于linux的解决方案)

java -classpath "./tagsoup-1.2.jar:./saxon9he.jar" \
    net.sf.saxon.Query \
   -x:org.ccil.cowan.tagsoup.Parser \
   -s:myrealLife.html \
   -qs://*:body

这项工作,但现在我尝试弄清楚如何设置default namespace以便能够通过示例//a直接查询

编辑2

我根据此POST创建了一个完整的github项目,请检查https://github.com/sputnick-dev/saxon-lint

2 个答案:

答案 0 :(得分:5)

我认为您不需要任何HTTP客户端。您可以使用doc()函数读取该文件,或者将其作为主输入文档提供,前提是您将其配置为使用HTML SAX解析器而不是XML解析器进行解析。如果你把John Cowan的TagSoup放在类路径上,那么用

调用Saxon
-x:org.ccil.cowan.tagsoup.Parser -s:myrealLife.html

应该这样做。

我认为你也可以使用validator.nu,它比HTMLS更快速地使用HTML5,但我自己没有尝试过。

答案 1 :(得分:1)

如果您查看EXPath HTTP客户端的文档,您将看到如果您使用它检索HTML,并且服务器使用HTML Internet媒体类型进行响应,那么HTML将自动整理为有效的XML格式,请参阅此处http://expath.org/spec/http-client#d2e517

因此,您无需编写任何Java代码即可实现目标。

您的XQuery不正确,因为您尝试使用eXist-db的HTTP客户端,而您声明要使用EXPath HTTP客户端。所以你应该将你的XQuery更改为:

xquery version "1.0";

declare namespace http="http://expath.org/ns/http-client";

let $url := 'http://stackoverflow.com'
let $response := http:send-request(
   <http:request href="{$url}" method="get"/>
) return
    <echo-results>
        {$response}
    </echo-results>

但是,您还需要说服Saxon加载并使用EXPath HTTP Client模块,默认情况下,Saxon没有HTTP Client的本机支持,请参阅http://saxonica.com/documentation/index.html#!functions

您可以在此处找到Saxon的EXPath HTTP客户端实现:https://code.google.com/p/expath-http-client/downloads/list如果您下载最新的Zip文件,则inside是一个README文件,它告诉您如何将它与Saxon一起使用。