2011-11-23 30 views
17

Xin chào, tôi muốn phân tích xml/rss từ url trực tiếp như http://rss.news.yahoo.com/rss/entertainment bằng cách sử dụng Java Script thuần túy (không phải jquery). Tôi đã googled rất nhiều. Không có gì làm việc cho tôi. bất kỳ ai có thể trợ giúp với một đoạn mã hoạt động.Phân tích cú pháp XML/RSS từ URL bằng cách sử dụng Java Script

+1

Có gì sai khi sử dụng jQuery? (nó làm cho mọi thứ trở nên dễ dàng hơn nhiều) – Nathan

+0

Tại sao bạn không thử jQuery? – Raptor

+3

Xin lỗi .. Tôi chỉ sử dụng Java Script trong tác vụ này. –

Trả lời

35

(Bạn không thể có googled rất nhiều.) Một khi bạn đã worked around the Same Origin Policy, và nếu tài nguyên được phục vụ với một XML MIME type (mà it is in this case, text/xml), bạn có thể làm như sau:

var x = new XMLHttpRequest(); 
x.open("GET", "http://feed.example/", true); 
x.onreadystatechange = function() { 
    if (x.readyState == 4 && x.status == 200) 
    { 
    var doc = x.responseXML; 
    // … 
    } 
}; 
x.send(null); 

(Xem thêm AJAX, và các đặc điểm kỹ thuật XMLHttpRequest Level 2 [Dự thảo Working] cho prop sự kiện handler khác 2.)

Về bản chất: Không cần phân tích cú pháp. Nếu sau đó bạn muốn truy cập dữ liệu XML, hãy sử dụng các phương pháp chuẩn DOM Level 2+ Core hoặc DOM Level 3 XPath, ví dụ:

/* DOM Level 2 Core */ 
var title = doc.getElementsByTagName("channel")[0].getElementsByTagName("title")[0].firstChild.nodeValue; 

/* DOM Level 3 Core */ 
var title = doc.getElementsByTagName("channel")[0].getElementsByTagName("title")[0].textContent; 

/* DOM Level 3 XPath (not using namespaces) */ 
var title = doc.evaluate('//channel/title/text()', doc, null, 0, null).iterateNext(); 

/* DOM Level 3 XPath (using namespaces) */ 
var namespaceResolver = (function() { 
    var prefixMap = { 
    media: "http://search.yahoo.com/mrss/", 
    ynews: "http://news.yahoo.com/rss/" 
    }; 

    return function (prefix) { 
    return prefixMap[prefix] || null; 
    }; 
}()); 

var url = doc.evaluate('//media:content/@url', doc, namespaceResolver, 0, null).iterateNext(); 

(Xem thêm JSX:xpath.js cho thuận tiện, không gian tên-aware DOM 3 XPath wrapper mà không sử dụng jQuery.)

Tuy nhiên, nếu vì một số (sai) lý do kiểu MIME không phải là một MIME XML hoặc nếu nó không được công nhận bởi việc triển khai DOM như vậy, bạn có thể sử dụng một trong các trình phân tích cú pháp được tích hợp vào các trình duyệt gần đây để phân tích giá trị thuộc tính responseText. Xem pradeek's answer để biết giải pháp hoạt động trong IE/MSXML. Thông tin sau đây sẽ hoạt động ở mọi nơi khác:

var parser = new DOMParser(); 
var doc = parser.parseFromString(x.responseText, "text/xml"); 

Tiến hành như mô tả ở trên.

Sử dụng kiểm tra tính năng khi chạy để xác định chi nhánh mã chính xác cho một triển khai nhất định. Cách đơn giản nhất là:

if (typeof DOMParser != "undefined") 
{ 
    var parser = new DOMParser(); 
    // … 
} 
else if (typeof ActiveXObject != "undefined") 
{ 
    var xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); 
    // … 
} 

Xem thêm DOMParserHTML5: DOM Parsing and Serialization (Working Draft).

10

Một vấn đề lớn mà bạn có thể gặp phải là nói chung, bạn không thể nhận được tên miền chéo dữ liệu. Đây là vấn đề lớn với hầu hết các nguồn cấp dữ liệu rss.

Cách phổ biến để xử lý dữ liệu tải trong miền chéo javascript là các cuộc gọi JSONP. Về cơ bản, điều này có nghĩa là dữ liệu bạn đang truy xuất được gói trong hàm gọi lại javascript. Bạn tải url bằng thẻ tập lệnh và bạn xác định hàm trong mã của mình. Vì vậy, khi kịch bản tải, nó thực hiện chức năng và chuyển dữ liệu vào nó như một đối số.

Sự cố với hầu hết nguồn cấp dữ liệu xml/rss là các dịch vụ chỉ cung cấp xml có xu hướng không cung cấp khả năng gói JSONP.

Trước khi bạn đi xa hơn, hãy kiểm tra xem liệu nguồn dữ liệu của bạn có cung cấp định dạng json và chức năng JSONP hay không. Điều đó sẽ làm cho việc này dễ dàng hơn nhiều.

Bây giờ, nếu nguồn dữ liệu của bạn không cung cấp chức năng json và jsonp, bạn phải sáng tạo.

Cách tương đối dễ dàng để xử lý việc này là sử dụng máy chủ proxy. Proxy của bạn chạy ở đâu đó dưới sự kiểm soát của bạn và hoạt động như một người trung gian để lấy dữ liệu của bạn. Máy chủ tải xml của bạn và sau đó javascript của bạn thực hiện các yêu cầu cho nó. Nếu máy chủ proxy chạy trên cùng một tên miền thì bạn chỉ có thể sử dụng các yêu cầu xhr (ajax) chuẩn và bạn không phải lo lắng về các công cụ đa miền.

Cách khác, máy chủ proxy của bạn có thể bọc dữ liệu trong một cuộc gọi lại jsonp và bạn có thể sử dụng phương pháp được đề cập ở trên.

Nếu bạn đang sử dụng jQuery, sau đó yêu cầu xhr và jsonp là các phương thức tích hợp sẵn và do đó làm cho việc viết mã trở nên dễ dàng. Các thư viện js phổ biến khác cũng nên hỗ trợ các thư viện này. Nếu bạn đang mã hóa tất cả điều này từ đầu, nó làm việc nhiều hơn một chút nhưng không quá khó khăn.

Bây giờ, một khi bạn nhận được dữ liệu của bạn hy vọng nó chỉ là json. Sau đó, không cần phân tích cú pháp.

Tuy nhiên, nếu bạn phải kết thúc bằng phiên bản xml/rss và nếu bạn là jQuery, bạn có thể chỉ cần sử dụng jQuery.parseXML http://api.jquery.com/jQuery.parseXML/.

0

chuyển đổi tốt hơn xml thành json. http://jsontoxml.utilities-online.info/

sau khi chuyển đổi nếu bạn cần in đối tượng json kiểm tra hướng dẫn này http://www.w3schools.com/json/json_eval.asp

+0

Chuyển đổi XML sang JSON có thể hữu ích cú pháp (các trình truy cập ngắn hơn, hiệu suất tốt hơn) nếu được thực hiện đúng - nghĩa là, nếu không gian tên XML được xem xét - nhưng điều đó là không cần thiết và cấu trúc dữ liệu kết quả kém linh hoạt hơn một tài liệu XML (JSPath, JSSLT bất kỳ ai?). (Thật không may, URI đầu tiên của bạn tương thích với 404.) BTW, W3Schools (không liên quan gì đến W3C) là một trang web đầy đủ thông tin sai lạc, tốt nhất nên tránh. – PointedEars

+0

Bây giờ trang Web đã trực tuyến trở lại, tôi có thể xem lại trình chuyển đổi. Nó thực sự không phải là xấu. Không gian tên và Unicode được xem xét; tên thuộc tính là "' -' "-prefixed; các nút có cùng tên là mảng-ified; thậm chí lỗi phân tích cú pháp được tuần tự hóa. Có phòng để cải thiện, mặc dù. Ví dụ: Tất cả các giá trị được tuần tự hóa là các chuỗi; đối với các thuộc tính boolean, bạn có thể đã tiết kiệm được một chút chi phí bằng 'true', là một phần của JSON. Và chuyển đổi không phải là tính từ (khi có thể): toJSON (toXML (json))! = Json. – PointedEars

+0

@NathanSri Liên kết đầu tiên đó đã chết, bạn có thể cập nhật câu trả lời của mình không? – Hugo

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