2012-06-13 37 views
6

Tôi đang cố gắng lấy tất cả văn bản trong nút cho tập hợp sau và trả về dưới dạng một giá trị (không phải nhiều nút).XPath để nhận tất cả văn bản trong phần tử dưới dạng một giá trị, hãy xóa ngắt dòng

<p> 
    "I love eating out." 
    <br> 
    <br> 
    "This is my favorite restaurant." 
    <br> 
    "I will definitely be back" 
</p> 

Tôi đang sử dụng '/ p' và nhận tất cả kết quả nhưng trả về bằng ngắt dòng. Đồng thời, thử kết quả '/ p/text()' trong việc nhận từng văn bản giữa mỗi thẻ dưới dạng giá trị trả lại riêng biệt. Sự trở lại lý tưởng sẽ là -

"I love eating out. This is my favorite restaurant. I will definitely be back" 

Tôi đã thử tìm kiếm các câu hỏi khác nhưng không thể tìm thấy điều gì gần gũi. Xin lưu ý rằng trong môi trường hiện tại, tôi bị hạn chế chỉ sử dụng truy vấn XPath và không thể phân tích cú pháp sau hoặc thiết lập bất kỳ phân tích cú pháp trước HTML nào. Cụ thể là tôi đang sử dụng hàm importXML bên trong Google Tài liệu.

+0

Chỉ cần chọn văn bản của tất cả các hậu duệ của ' p' với '/ p // */text()'. Truy cập nội dung của nút văn bản bằng 'textContent'. Bạn sẽ vẫn cần ghép chúng lại với nhau. – nhahtdh

Trả lời

7

Sử dụng:

normalize-space(/) 

Khi biểu thức XPath này được đánh giá, chuỗi giá trị của nút văn bản (/) là lần đầu tiên được sản xuất và điều này được cung cấp như là đối số cho hàm XPath chuẩn normalize-space().

Theo định nghĩa, normalize-space() trả về đối số của nó với các ký tự khoảng trắng liền kề và cuối cùng bị loại bỏ và bất kỳ nhóm ký tự khoảng trắng liền kề nào được thay thế bằng một ký tự khoảng trắng.

Việc đánh giá các kết quả biểu thức XPath trên trong:

"Tôi thích ăn ở ngoài." "Đây là nhà hàng yêu thích của tôi." "Tôi chắc chắn sẽ trở lại"

Để loại bỏ các dấu ngoặc kép, chúng tôi bổ sung sử dụng translate() chức năng:

normalize-space(translate(/,'&quot;', '')) 

Kết quả của việc đánh giá biểu thức này là:

I love eating out. This is my favorite restaurant. I will definitely be back 

Cuối cùng, để có kết quả này được bao bọc trong dấu ngoặc kép, chúng tôi sử dụng hàm concat() :

concat('&quot;', 
     normalize-space(translate(/,'&quot;', '')), 
     '&quot;' 
     ) 

Việc đánh giá các biểu thức XPath này tạo ra chính xác những kết quả mong muốn:

"I love eating out. This is my favorite restaurant. I will definitely be back" 

XSLT - dựa xác minh:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:template match="/"> 
    <xsl:value-of select= 
    "concat('&quot;', 
      normalize-space(translate(/,'&quot;', '')), 
      '&quot;' 
      )"/> 
</xsl:template> 
</xsl:stylesheet> 

Khi chuyển đổi này được áp dụng trên tài liệu XML được cung cấp (chính xác ed được thực hiện tốt được hình thành):

biểu
<p> 
     "I love eating out." 
     <br /> 
     <br /> 
     "This is my favorite restaurant." 
     <br /> 
     "I will definitely be back" 
</p> 

XPath được đánh giá và kết quả của đánh giá này được sao chép vào đầu ra:

"I love eating out. This is my favorite restaurant. I will definitely be back" 
+1

Phản hồi tuyệt vời. Khi tôi sử dụng bình thường hóa không gian đối với các tập dữ liệu tương tự trên một trang, thay vì trả về nhiều giá trị đơn, nó chỉ là một giá trị duy nhất được trả về cho toàn bộ trang (ngay cả khi có nhiều trẻ em có dữ liệu tương tự mà tôi đã cố trích xuất). Mục tiêu của tôi là đánh giá nhiều khu vực tương tự trên trang và trả về từng khu vực dưới dạng một giá trị. –

+0

@RichardOrtega: Đây không phải là biểu thức XPath 1.0 * duy nhất (với XPath 2.0, có thể viết một biểu thức đơn để tạo ra một chuỗi chứa chính xác các chuỗi mong muốn). Vì vậy, với XPath 1.0 bạn sẽ cần phải chọn từng nút văn bản và xử lý từng nút được chọn bằng ngôn ngữ lập trình đang lưu trữ XPath. Nếu bạn quan tâm đến một giải pháp XSLT - chỉ cần hỏi một câu hỏi mới và cho tôi biết :) –

+0

cảm ơn bạn rất nhiều, bạn đã giúp đỡ rất nhiều! Rất thông tin, đó là một trong những lần đầu tiên tôi sử dụng XPath. –

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