如何?xmlstarlet通过id提取HTML数据

mat*_*cky 12 xml xhtml xmlstarlet

我有一个简单的任务,让我把头发拉出来,我敢肯定我非常接近.

这是我的xhtml文件:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<title>Test Page</title>
</head>

<body>

<p>
test
</p>

<table id="test_table">
<tr><td>test</td><td>test</td></tr>
<tr><th>mo test</th></tr>
</table>

</body>

</html>
Run Code Online (Sandbox Code Playgroud)

...和xmlstarlet喜欢它:

$ xmlstarlet.exe el -v test.xhtml
html[@xmlns='http://www.w3.org/1999/xhtml']
html/head
html/head/title
html/body
html/body/p
html/body/table[@id='test_table']
html/body/table/tr
html/body/table/tr/td
html/body/table/tr/td
html/body/table/tr
html/body/table/tr/th
Run Code Online (Sandbox Code Playgroud)

我需要做的是提取表标签中的数据,最好不要使用HTML.对此的上下文是我正在编写一个测试集,其中一个网页被调用然后写入文件.测试要求我验证表数据,但如果页面上的其他内容发生变化,则允许测试成功.此外,我不会事先知道该表将包含多少列或行,它可能会根据数据而有所不同.

但是当我尝试:

$ xmlstarlet.exe sel -t -c "/html/body/table[@id='test_table']" test.xhtml
Attempt to load network entity http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
None of the XPaths matched; to match a node in the default namespace
use '_' as the prefix (see section 5.1 in the manual).
For instance, use /_:node instead of /node
Run Code Online (Sandbox Code Playgroud)

我需要不同的id进行不同的测试,但它们都有唯一的id值.所以,给定xhthml中的任何'id',我需要它的数据.

提前致谢.

Bir*_*rei 8

html数据有你在声明一个默认命名空间xmlstarlet的命令:

xmlstarlet sel \
    -N n="http://www.w3.org/1999/xhtml" \
    -t \
    -c "/n:html/n:body/n:table[@id='test_table']/descendant::*/text()" \
htmlfile 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

一旦找到<table>descendant::*/text()用来提取它的所有文本元素的元素,并且还用于2>/dev/null跳过警告:

Attempt to load network entity http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
Run Code Online (Sandbox Code Playgroud)

它产生:

testtestmo test
Run Code Online (Sandbox Code Playgroud)

更新:我不知道它,但正如错误消息所示,没有必要声明命名空间时它是默认的,所以这也有效:

xmlstarlet sel \
    -t \
    -c "/_:html/_:body/_:table[@id='test_table']/descendant::*/text()" \
htmlfile 2>/dev/null
Run Code Online (Sandbox Code Playgroud)

  • 多年来,我一直通过“tidy -q -asxml”运行 HTML,它会生成命名空间的 (X)HTML,并且想知道为什么“xmlstarlet sel”不会产生任何结果,因为给出了一个完全合理的 XPath 表达式,如“//title” ` 与其他工具配合得很好。您现在让我了解了命名空间的存在和可能性(!),并且关于使用“_”作为默认命名空间的提示是纯金的。非常感谢! (2认同)