如何在命令行中使用 XPath 和 Saxon-HE 解析 HTML?
How to parse HTML using XPath with Saxon-HE in command line?
我使用 saxon HE 9.6,它非常适合在解析格式良好的 XML 文件时使用 XPath 3。
但我想知道如何组合 expath-http-client (or any other working solution) with Saxon 以具有解析 realLife©®™(可能损坏)HTML 的能力。 (Java不是我的强项)。
我搜索了 google 好几个小时都没有找到任何可行的解决方案。我试过类似的东西:
xquery_file.xsl :
xquery version "1.0";
declare namespace http="http://expath.org/ns/http-client";
let $url := 'http://whosebug.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
我已经根据这个帖子创建了一个完整的github项目,查看https://github.com/sputnick-dev/saxon-lint
如果您查看 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://whosebug.com'
let $response := http:send-request(
<http:request href="{$url}" method="get"/>
) return
<echo-results>
{$response}
</echo-results>
但是,您还需要说服 Saxon 加载和使用 EXPath HTTP 客户端模块,默认情况下 Saxon 没有对 HTTP 客户端的本地支持,请参阅 http://saxonica.com/documentation/index.html#!functions。
您可以在此处找到 Saxon 的 EXPath HTTP 客户端实现:https://code.google.com/p/expath-http-client/downloads/list 如果您下载最新的 Zip 文件,里面有一个 README 文件,告诉您如何将它与 Saxon 一起使用。
我认为您不需要为此使用任何 HTTP 客户端。您可以使用 doc() 函数读取文件,或将其作为主要输入文档提供,前提是您将其配置为使用 HTML SAX 解析器而不是 XML 解析器进行解析。如果将 John Cowan 的 TagSoup 放在类路径中,则使用
调用 Saxon
-x:org.ccil.cowan.tagsoup.Parser -s:myrealLife.html
应该可以解决问题。
我想你也可以使用 validator.nu,HTML5 比 TagSoup 更快,但我自己还没有尝试过。
我使用 saxon HE 9.6,它非常适合在解析格式良好的 XML 文件时使用 XPath 3。
但我想知道如何组合 expath-http-client (or any other working solution) with Saxon 以具有解析 realLife©®™(可能损坏)HTML 的能力。 (Java不是我的强项)。
我搜索了 google 好几个小时都没有找到任何可行的解决方案。我试过类似的东西:
xquery_file.xsl :
xquery version "1.0";
declare namespace http="http://expath.org/ns/http-client";
let $url := 'http://whosebug.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
我已经根据这个帖子创建了一个完整的github项目,查看https://github.com/sputnick-dev/saxon-lint
如果您查看 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://whosebug.com'
let $response := http:send-request(
<http:request href="{$url}" method="get"/>
) return
<echo-results>
{$response}
</echo-results>
但是,您还需要说服 Saxon 加载和使用 EXPath HTTP 客户端模块,默认情况下 Saxon 没有对 HTTP 客户端的本地支持,请参阅 http://saxonica.com/documentation/index.html#!functions。
您可以在此处找到 Saxon 的 EXPath HTTP 客户端实现:https://code.google.com/p/expath-http-client/downloads/list 如果您下载最新的 Zip 文件,里面有一个 README 文件,告诉您如何将它与 Saxon 一起使用。
我认为您不需要为此使用任何 HTTP 客户端。您可以使用 doc() 函数读取文件,或将其作为主要输入文档提供,前提是您将其配置为使用 HTML SAX 解析器而不是 XML 解析器进行解析。如果将 John Cowan 的 TagSoup 放在类路径中,则使用
调用 Saxon-x:org.ccil.cowan.tagsoup.Parser -s:myrealLife.html
应该可以解决问题。
我想你也可以使用 validator.nu,HTML5 比 TagSoup 更快,但我自己还没有尝试过。