簡體   English   中英

如何使用Ruby和Nokogiri解析LI / DL / DD標簽結構?

[英]How do I parse LI/DL/DD tag structure using Ruby and Nokogiri?

我正在嘗試解析既包含有序列表又包含DL / DD標簽的html。 目標是創建一個XML結構,該結構逐項列出EACH標簽的內容並添加一些屬性。 最終使結構變平(問題的結尾將顯示所需的輸出)。

這是一個存儲在文件中的html示例(包含在我的代碼中的test.html中):

<!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" xml:lang="en" lang="en" dir="ltr">  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
<title>Test Structure</title>  
</head>  
<body>  
<ol><li>Item 1 - Level 1  
<dl><dd>Item 1.1 - Level 2  
</dd><dd>Item 1.2 - Level 2  
</dd></dl>  
</li><li>Item 2 - Level 1  
<dl><dd>Item 2.1 - Level 2  
<dl><dd>Item 2.1.1 - Level 3  
</dd><dd>Item 2.1.2 - Level 3  
<dl><dd>Item 2.1.2.1 - Level 4  
</dd><dd>Item 2.1.2.2 - Level 4  
</dd></dl>  
</dd></dl>  
</dd><dd>Item 2.2 - Level 2  
<dl><dd>Item 2.2.1 - Level 3  
</dd><dd>Item 2.2.2 - Level 3  
<dl><dd>Item 2.2.2.1 - Level 4  
</dd><dd>Item 2.2.2.2 - Level 4  
</dd></dl>  
</dd><dd>Item 2.2.3 - Level 3  
<dl><dd>Item 2.2.3.1 - Level 4  
</dd><dd>Item 2.2.3.2 - Level 4  
</dd></dl>  
</dd><dd>Item 2.2.4 - Level 3  
</dd></dl>  
</dd></dl>  
</li><li>Item 3 - Level 1  
<dl><dd>Item 3.1 - Level 2  
</dd><dd>Item 3.2 - Level 2  
</dd></dl>  
</li></ol>  
</body>  
</html>

HTML的輸出(在這里顯示,您看不到瀏覽器中的縮進):

 
 
 
  1. Item 1 - Level 1
    Item 1.1 - Level 2
    Item 1.2 - Level 2
  2. Item 2 - Level 1
    Item 2.1 - Level 2
    Item 2.1.1 - Level 3
    Item 2.1.2 - Level 3
    Item 2.1.2.1 - Level 4
    Item 2.1.2.2 - Level 4
    Item 2.2 - Level 2
    Item 2.2.1 - Level 3
    Item 2.2.2 - Level 3
    Item 2.2.2.1 - Level 4
    Item 2.2.2.2 - Level 4
    Item 2.2.3 - Level 3
    Item 2.2.3.1 - Level 4
    Item 2.2.3.2 - Level 4
    Item 2.2.4 - Level 3
  3. Item 3 - Level 1
    Item 3.1 - Level 2
    Item 3.2 - Level 2

所需的輸出:

<job>  
<req level='1'>Item 1 - Level 1</req>  
<req level='1.1'>Item 1.1 - Level 2</req>  
<req level='1.2'>Item 1.2 - Level 2</req>  
<req level='2'>Item 2 - Level 1</req>  
<req level='2.1'>Item 2.1 - Level 2</req>  
<req level='2.1.1'>Item 2.1.1 - Level 3</req>  
<req level='2.1.2'>Item 2.1.2 - Level 3</req>  
<req level='2.1.2.1'>Item 2.1.2.1 - Level 4</req>  
<req level='2.1.2.2'>Item 2.1.2.2 - Level 4</req>  
<req level='2.2'>Item 2.2 - Level 2</req>  
<req level='2.2.1'>Item 2.2.1 - Level 3</req>  
<req level='2.2.2'>Item 2.2.2 - Level 3</req>  
<req level='2.2.2.1'>Item 2.2.2.1 - Level 4</req>  
<req level='2.2.2.2'>Item 2.2.2.2 - Level 4</req>  
<req level='2.2.3'>Item 2.2.3 - Level 3</req>  
<req level='2.2.3.1'>Item 2.2.3.1 - Level 4</req>  
<req level='2.2.3.2'>Item 2.2.3.2 - Level 4</req>  
<req level='2.2.4'>Item 2.2.4 - Level 3</req>  
<req level='3'>Item 3 - Level 1</req>  
<req level='3.1'>Item 3.1 - Level 2</req>  
<req level='3.2'>Item 3.2 - Level 2</req>  
</job>

請注意,我們要從遍歷結構中得出層次結構,而不是從每個LI和DD屬性的實際內容中得出...我的示例內容列出了層次結構(1、1.1、1.2 ...),但在實際數據,我們看不到。 “級別”屬性應反映結構的遍歷。

我對Ruby和Nokogiri都是陌生的,但這是我嘗試閱讀HTML的嘗試(不必創建XML)。 我被困在分離出LI節點和內容。 我試過使用.eachchildren.each等:

require 'rubygems'  
require 'open-uri'  
require 'nokogiri'  

url = "test.html"  
doc = Nokogiri::HTML(open(url))  
line = "1"  
doc.css("ol[1]").children.each do |n|  
    puts line + n.content.to_s  
    line.succ!  
    n.children do |c|  
        puts line + c.content.to_s  
        line.succ!  
    end  
end  

您可以使用node_name方法來確定什么是文本和什么是子項,這是一個示例函數,它在ol下吐出html標簽的名稱:

def traverse(node, indent = 0)
  node.children.each do |child|
    next if child.node_name == "text"
    puts "  "*indent + child.node_name
    traverse(child, indent+1)
  end
end

traverse doc.css("ol[1]")

(我在上面跳過的文本節點是標記的文本內容)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM