2014-02-25 29 views
12

我有一個簡單的任務,讓我拉我的頭髮,我敢肯定我非常接近。如何? xmlstarlet通過id提取HTML數據

這裏是我的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> 

...和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 

什麼,我需要做的是提取表標籤中的數據,最好是沒有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 

有不同的id我需要不同的測試,但它們都具有唯一的ID值。所以,鑑於xhthml中的任何'id',我需要它的數據。

在此先感謝。

回答

7

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 

一旦位於<table>元素我用descendant::*/text()提取它的所有文字元素,並且還使用2>/dev/null跳過警告:

Attempt to load network entity http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd 

它產生:

testtestmo test 

更新:我不知道,但作爲錯誤消息說,沒有必要宣佈該命名空間時,它的默認之一,因此也是這個原理:

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

謝謝謝謝謝謝!現在我明白錯誤信息了!但是,我也永遠不會猜到後代的語法。 –

0

由於使用

時在

http://xmlstar.sourceforge.net/doc/UG/ch05.html

常見問題中提到

-N x="http://www.w3.org/1999/xhtml" \ 

選項,你也有

x: 

例如前綴節點的選擇

xmlstarlet sel \ 
    -N x="http://www.w3.org/1999/xhtml" \ 
    -t \ 
    -m "//x:pre" \ 
    -v . somehtml.html 

將選擇所有預節點

-1

您可以嘗試

xmlstarlet ed --inplace -u "html/body/table[@id='your_tabl e_id']/tr[@id='row_id']/td[@id='data_id']" -v NEW_VALUE_TO_BE_CHANGED HTMLFILE_NAME 2>/dev/null 
+0

這肯定會起作用 –