2012-02-08 28 views
6

Hãy nói rằng tôi có mã này:Chọn nodeValue nhưng loại trừ yếu tố con

<p dataname="description"> 
Hello this is a description. <a href="#">Click here for more.</a> 
</p> 

Làm thế nào để chọn nodeValue của p nhưng loại trừ a và đó là nội dung?

mã hiện tại của tôi:

$result = $xpath->query("//p[@dataname='description'][not(self::a)]"); 

Tôi chọn nó bằng cách $result->item(0)->nodeValue;

Trả lời

10

Đơn giản chỉ cần thêm/text() để truy vấn của bạn nên làm các trick

$result = $xpath->query("//p[@dataname='description'][not(self::a)]/text()"); 
+0

thể u pls giải thích tại sao nó lại như vậy? – Michelle

+2

Nếu không có/text() bạn chọn toàn bộ nút bao gồm cả trẻ em. Các nút phần tử không có văn bản, thay vào đó văn bản được lưu trữ trong nút con được gọi là nút văn bản. nodeValue được sử dụng để lấy giá trị văn bản của một nút. Gọi nodeValue trên một nút với trẻ em nhận được tất cả các nút văn bản con và nối chúng. Với/text() bạn chỉ lấy nút con đầu tiên của văn bản kiểu, và do đó chỉ nhận được văn bản của nút văn bản này – Kristofer

2

Không chắc chắn nếu XPath của PHP hỗ trợ này, nhưng XPath này các trick cho tôi trong Scrapy (Python dựa khuôn khổ cào):

$xpath->query('//p[@dataname='description']/text()[following-sibling::a]') 

Nếu cách này không hiệu quả, hãy thử giải pháp Kristoffers hoặc bạn cũng có thể sử dụng giải pháp regex. Ví dụ:

$output = preg_replace("~<.*?>.*?<.*?>~msi", '', $result->item(0)->nodeValue);

Điều đó sẽ loại bỏ bất kỳ thẻ HTML với bất kỳ nội dung trong đó, trừ văn bản mà không được đóng gói bằng các thẻ HTML.

Các vấn đề liên quan