2009-05-08 15 views
5

Tôi có tài liệu XML sau:Làm cách nào để Nokogiri hiểu được không gian tên của tôi?

<samlp:LogoutRequest ID="123456789" Version="2.0" IssueInstant="200904051217"> 
    <saml:NameID>@[email protected]</saml:NameID> 
    <samlp:SessionIndex>abcdefg</samlp:SessionIndex> 
</samlp:LogoutRequest> 

Tôi muốn để có được nội dung của SessionIndex (có nghĩa là, 'abcdefg') ra khỏi nó. Tôi đã thử điều này:

XPATH_QUERY = "LogoutRequest[@ID][@Version='2.0'][IssueInstant]/SessionIndex" 
SAML_XMLNS = 'urn:oasis:names:tc:SAML:2.0:assertion' 
SAMLP_XMLNS = 'urn:oasis:names:tc:SAML:2.0:protocol' 

require 'nokogiri' 
doc = Nokogiri::XML(xml) 
doc.xpath(XPATH_QUERY, 'saml' => SAML_XMLNS, 'samlp' => SAMLP_XMLNS) 

nhưng tôi nhận được các lỗi sau đây:

Nokogiri::XML::SyntaxError: Namespace prefix samlp on LogoutRequest is not defined 
Nokogiri::XML::SyntaxError: Namespace prefix saml on NameID is not defined 
Nokogiri::XML::SyntaxError: Namespace prefix samlp on SessionIndex is not defined 

Tôi đã thử thêm các không gian tên với truy vấn XPath, nhưng điều đó không thay đổi bất cứ điều gì.

Tại sao tôi không thể thuyết phục Nokogiri rằng các không gian tên hợp lệ?

Trả lời

6

Dường như không gian tên trong tài liệu này được khai báo chính xác - phải có thuộc tính xmlns:samlpxmlns:saml trên nút gốc. Trong những trường hợp như thế này, về cơ bản Nokogiri bỏ qua các không gian tên (vì nó không thể ánh xạ họ URI hoặc Đỉnh), do đó XPath của bạn hoạt động nếu bạn loại bỏ chúng, ví dụ:

doc.xpath(XPATH_QUERY) 
+0

Đó dường như để cho tôi những lỗi tương tự ... trong một số tình huống. Làm nó theo nghĩa đen trong irb hoạt động tốt, nhưng chạy thông số kỹ thuật của tôi vẫn thổi lên. Garr. –

+0

OK! Nokogiri trả về một nút "lỗi" bao bọc nút mà nó tìm thấy, nhưng nó là _really_did_find_the_node_! –

9

tôi nhìn thấy một hai lựa chọn khác nhau cho bạn:

  1. Hủy bỏ tất cả các không gian tên

    http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Document#remove_namespaces%21-instance_method

    Brute cách lực lượng để làm việc đó. Có thể dẫn đến các sự cố khi có xung đột không gian tên.

  2. Sử dụng collect_namespaces

    http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Document#collect_namespaces-instance_method

    Một giải pháp tốt hơn nhiều. Bạn có thể sử dụng điều này một lần để xác định các không gian tên (nói trong irb) và mã hóa chúng.

    HOẶC

    Sử dụng nó khi chạy, và cung cấp nó như là đối số thứ hai để http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Node#xpath-instance_method

+0

'collect_namespaces' là một điều tốt để biết – mikezter

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