2009-10-21 17 views
5

Hãy xem xét điều này:khác biệt trong jQuery với namespace XML và xhr.responseXML giữa Opera và Firefox

<!DOCTYPE HTML> 
<html><head><title>XML-problem</title> 

<script src="jquery-1.3.2.min.js" type="text/javascript"></script> 

<script type="text/javascript"> 

$(function() { 
    $('<p/>').load("text.xml", function(responseText, textStatus, xhr) { 
     var xml = $(xhr.responseXML); 
     var x_txt = xml.find('atom\\:x').text(); 
     $(this).text(x_txt).appendTo('#container'); 
    }); 
}); 

</script> 

</head><body><div id="container" /></body></html> 

kịch bản này nên tải text.xml khi tài liệu đã được tải. text.xml trông như thế này:

<xml xmlns:atom="http://www.w3.org/2005/Atom"> 
    <atom:x>Text</atom:x> 
</xml> 

Khi tập tin này đã được kích hoạt, nội dung văn bản của atom:x -node sẽ được nối vào tài liệu. Tôi có thể thấy "Văn bản" trong cửa sổ trình duyệt của mình.

Điều này hoạt động như mong đợi trong Firefox. Tuy nhiên, nó không hoạt động trong Opera trừ khi tôi thay đổi truy vấn từ 'atom\\:x' thành chỉ 'x'. Trong trường hợp này nó hoạt động trong Opera, nhưng không phải Firefox.

Tôi đã phát hiện ra giải pháp thay thế, cụ thể là thay đổi truy vấn thành 'atom\\:x, x', nhưng tôi muốn nhận được phần cuối của điều này.


Bây giờ cho các thay đổi vui nhộn: Tôi có thể inline xml trực tiếp thay vì nhận được nó từ XHR bằng cách thay đổi

var xml = $(xhr.responseXML); 

vào

var xml = $('<xml xmlns:atom="http://www.w3.org/2005/Atom"><atom:x>Text</atom:x></xml>'); 

Trong trường hợp này một truy vấn của 'atom\\:x' sẽ cung cấp kết quả mong muốn trong cả hai trình duyệt và chỉ 'x' sẽ không cho kết quả nào trong cả hai trình duyệt.

Sự kiện này hoạt động khác trong Opera khiến tôi kết luận rằng hành vi cũ là lỗi trong Opera. Đây có phải là một kết luận hợp lý không? Tôi có thể chỉ ra tiêu chuẩn nào mô tả cách thức hoạt động của nó?


Tóm lại:

  1. các công việc ở quanh thay thế cho vấn đề này là gì? Có tốt hơn cái tôi tìm thấy không?
  2. Đây có phải là lỗi trong Opera không? Nếu có, tiêu chuẩn nào nói như vậy?

Hy vọng bạn có thể giúp :)

+2

Trông giống như một lỗi đã lưu ý. http://thompson-web.blogspot.com/2009/03/jquery-xml-and-namespaces.html http://dev.jquery.com/ticket/155 –

+1

@Stefan: Vì vậy, jQuery nên cho tôi kết quả khi chỉ truy vấn 'x', bất kể trình duyệt là gì? –

+0

Tại sao bạn sử dụng 'tải'? Tải phải là html, không phải xml. Nó có hoạt động với 'ajax' hay' get' không? – Kobi

Trả lời

1

Tôi nghĩ bạn nên nói "nguyên tử: x" (không có gạch chéo ngược), và chắc chắn phải có xmlns: nguyên tử = "http: //www.w3 .org/2005/Atom "khai báo hoặc trên thẻ html trên tệp html chính, hoặc theo một số cách khác được biết đến với javascript.

+1

Điều đó sẽ * không * hoạt động. đại tràng là một nhân vật đặc biệt trong jquery và phải được trốn thoát. –

0

Thật khó để nói nếu đây là một lỗi trong opera hoặc nếu đây là một lỗi trong jQuery đó là Opera cụ thể. Từ âm thanh của nó, Opera không thêm đúng không gian tên vào dom tài liệu xhr và đây là lý do tại sao jQuery không thể truy vấn atom: x và cũng giải thích tại sao, khi bạn tạo nút jquery của riêng bạn, bạn không nhận được kết quả tương tự.

Điều đầu tiên tôi sẽ làm là thử và xem liệu nguyên tử có phải là một không gian tên được xác định trong dom xhr hay không. Nó sẽ trả về nguyên tử ns của bạn như được định nghĩa, Nếu không, đây có lẽ là một lỗi opera. Tôi không chắc chắn cách tốt nhất để kiểm tra điều này, nhưng có lẽ: xhr.getElementByTagNameNS("x" "http://www.w3.org/2005/Atom"); sẽ hoạt động.

Nếu không, Opera tuyên bố hỗ trợ XML namespaces, tuy nhiên, tôi sẽ mở một yêu cầu lỗi với jQuery và xem nơi bạn nhận được.

Ở các điểm khác, như tôi đã đề cập đến trong nhận xét của mình, tôi không nghĩ rằng việc truy vấn atom:x bởi x là một ý tưởng hay. Bạn cũng có thể không sử dụng không gian tên vì nó đánh bại mục đích.

+0

Cảm ơn lời khuyên. Thật không may, tôi sẽ không thể kiểm tra nó ngay lập tức ... Tôi sẽ trở lại với bạn. –

2

Tôi đã trải nghiệm hành vi này trong các phiên bản khác nhau của cùng một trình duyệt và theo tôi nhớ tại thời điểm tôi đang thử nghiệm trang có vấn đề với FF và IE, vì vậy tôi cho rằng đó không phải là lỗi dành riêng cho Opera .

Tôi muốn đề xuất rằng bất cứ khi nào bạn sử dụng jQuery để phân tích cú pháp thẻ XML với tiền tố không gian tên, bạn truy vấn bộ chọn cả có và không có tiền tố. Nghĩa là, thay vì sử dụng

var x_txt = xml.find('atom\\:x').text(); 

thử

var x_txt = xml.find('atom\\:x, x').text(); 

Tôi nghĩ rằng đây là một cách giải quyết có thể chấp nhận đối với hầu hết các tình huống và nó sẽ đảm bảo rằng kết quả của bạn là chính xác mặc dù cư xử xấu ...

3

Nó không phải là một lỗi trong Opera. Đó là the correct behavior:

Trong một máy khách nhận biết không gian tên, phần tên của bộ chọn loại phần tử (phần sau dấu phân cách không gian tên, nếu có) sẽ chỉ khớp với phần địa phương của tên đủ điều kiện của phần tử.

Trong trường hợp của bạn, tên địa phương là xatom:xisn't even a legal local name in XML.

Hơn nữa, namespace-prefixed type selector trong CSS có cú pháp khác nhau mà không sử dụng ruột kết ở tất cả:

@namespace atom url(http://www.w3.org/2005/Atom); 
atom|x { color: blue } 

cú pháp của bạn dường như dựa vào một điều không minh bạch được giới thiệu bởi parsers HTML trong sử dụng các đại lý không gian tên-không biết.

HTML phân tích cú pháp "ăn" ruột kết như là một phần của tên thẻ và bạn nhận atom:x phần tử trong không gian tên mặc định, mà sẽ phù hợp với atom\:x chọn, nhưng trong XML mà bạn nhận được x phần tử trong http://www.w3.org/2005/Atom namespace.

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