2011-08-14 36 views
13

Một số nút trong tài liệu XML có các không gian tên, được xác định bằng tiền tố được xác định.Tại sao không có cú pháp XPath cho các nút đủ điều kiện không gian tên?

Có thể chỉ định tên địa phương() trong XPath 1.0 và do đó bỏ qua không gian tên.

Tuy nhiên, tôi muốn cho phép tác giả của XPath tìm thấy các nút bằng cách sử dụng tên đủ điều kiện không gian tên đầy đủ của họ làm số nhận dạng.

Cách được khuyến nghị là thêm các khai báo không gian tên trong mã gọi (trong trường hợp của tôi là Java). Nhưng điều này có nghĩa là người viết Xpath không có khả năng làm việc với các không gian tên!

Làm cách nào để tìm các nút theo tên hoàn toàn đủ điều kiện của chúng bằng XPath thuần túy?

+2

Nếu tôi hiểu câu hỏi một cách chính xác, bạn sẽ hỏi tại sao cần khai báo một không gian tên bằng cách sử dụng lệnh như 'addNamespace (" abc "," http://example.com ")', sau đó cho phép thực hiện Truy vấn Xpath như '/ abc: node', thay vì bằng cách nào đó bằng cách sử dụng' http: // example.com' trực tiếp trong truy vấn. Tôi đã giải thích câu hỏi một cách chính xác chưa? –

+1

@Jong Bor Vâng, đúng vậy. Sẽ tốt hơn nếu sử dụng tiền tố abc trực tiếp trong truy vấn XPath sau khi khai báo rằng abc = http: //example.com bằng cách nào đó trong XPath. Tôi hiểu rằng các biểu thức XPath là ngắn và sẽ không bình thường khi chèn các định nghĩa vào nó, nhưng không có gì ngăn cản kỹ thuật điều đó trong XPath. –

+1

Câu hỏi hay về BTW, +1. Vì các tiền tố được coi là đường cú pháp không đáng kể, trong khi các URI không gian tên là quan trọng, bạn sẽ nghĩ rằng nó có thể hữu ích khi khớp trên một tên nút là URI không gian tên mà không phải gây rối với tiền tố - đặc biệt nếu XPath cung cấp không có cách nào để khai báo một tiền tố. – LarsH

Trả lời

13

Không chắc chắn ý bạn là "số nhận dạng".

Làm cách nào để tìm các nút theo tên hoàn toàn đủ điều kiện của chúng bằng XPath thuần túy?

Trong XPath 1.0, bằng cách sử dụng tên địa phương() và namespace-uri(), ví dụ:

"*[local-name() = 'foo' and namespace-uri() = 'http://my.org/ns/2.0']" 

Trong XPath 2.0, có một bộ chức năng phong phú hơn liên quan đến không gian tên, ví dụ: namespace-uri-from-QName(). Nhưng tôi không chắc họ cải thiện những điều trên mà bạn muốn.

+1

Tốt, có ý nghĩa. Một chút vụng về - tôi muốn viết một cái gì đó như http://my.org/ns/2.0|foo mà không có các tên hàm này, và thậm chí tốt hơn bằng cách nào đó sử dụng các tiền tố, khai báo chúng trong XPath thay vì trong Java - nhưng điều này không đáp ứng yêu cầu. –

+1

Bằng cách "sử dụng tên đủ điều kiện không gian tên đầy đủ của họ làm mã định danh", tôi chỉ có nghĩa là bạn có thể tham chiếu chính xác các nút, với không gian tên + tên địa phương. Câu trả lời của bạn cho thấy như thế nào. –

+0

@JoshuaFox: Tôi đồng ý, sẽ rất tiện dụng để có thể khai báo tiền tố trong chính XPath. Tôi tưởng tượng có một số lý do tại sao "họ" quyết định không bao gồm trong XPath, nhưng nó có vẻ như một khoảng cách lớn, kể từ khi workaround là như vậy tiết. – LarsH

1

Bạn có thể sử dụng không gian tên trong các truy vấn XPath của bạn. Trong Java, những gì bạn cần cung cấp là triển khai NamespaceContext nếu bạn cũng muốn sử dụng tiền tố trong các truy vấn đó thay vì không gian tên đủ điều kiện mọi lúc. Chỉ cần thêm một thể hiện của NamespaceContext vào XPath - Tôi sẽ giả sử bạn sử dụng triển khai JDK chuẩn - nhưng khái niệm này cũng có thể áp dụng cho Jaxen hoặc các khái niệm khác.

Sau đó, bạn có thể thực hiện các truy vấn như //customns:Element.

Nếu bạn không hoặc không thể sử dụng một NamespaceContext (vì lý do gì) thì giải pháp duy nhất dường như được sử dụng local-namenamespace-uri chức năng:

Document doc = ...; 
XPath xp = XPathFactory.newInstance().newXPath(); 
String name = "Element"; 
String ns = "http://www.custom.org/#"; 
String expr = "//*[local-name() = '"+name+" and namespace-uri() = '"+ns+"']"; 
Node node = ((NodeList)xp.evaluate(expr, doc, XPathConstants.NODESET)).item(0); 
+1

Cảm ơn. Điều gì sẽ xảy ra nếu tôi sẵn sàng sử dụng tên không gian tên đầy đủ và không phải là tiền tố? Nói cách khác, một cái gì đó như thế nào. Tôi có thể tránh khai báo các không gian tên trong Java không? Mục tiêu của tôi là đọc các biểu thức XPath từ một nguồn bên ngoài, và vì vậy tôi không muốn chỉ rõ điều này một cách riêng biệt. –

+0

Điều đó phụ thuộc vào cách nguồn trông như thế nào - nếu bạn chỉ có một biểu thức // abc: Phần tử và không có khai báo không gian tên thì theo lý thuyết bạn bị mắc kẹt - không có cách nào để biết abc trỏ tới điểm nào. Nhưng nếu bạn hoàn toàn có thể chắc chắn rằng những biểu thức bên ngoài đó có cùng tiền tố với tài liệu làm việc của bạn, thì bạn vẫn có thể tra cứu các không gian tên tương ứng trong tài liệu của bạn và sau đó xây dựng một NamespaceContext hoặc không sử dụng nó. Tôi sẽ cập nhật câu trả lời của tôi phác thảo cách làm như vậy. – emboss

+0

Thật không may, có vẻ như [không có giải pháp khác] (http://www.jguru.com/forums/view.jsp?EID=1073634) so ​​với kết hợp tên địa phương() và không gian tên-uri(). – emboss

4

XPath 3.0, mà hiện nay đang làm việc trạng thái dự thảo, sẽ bao gồm một biểu thức nghĩa đen cho URI qualified QNames cho phép trực tiếp chỉ định không gian tên uri.

Dưới đây là một số ví dụ về EQNames:

  • pi là một QName từ vựng mà không có một tiền tố namespace.
  • phép tính: pi là một QName từ vựng với tiền tố không gian tên.
  • "http://www.w3.org/2005/xpath-functions/math":pi chỉ định URI vùng tên bằng URILiteral; nó không phải là một QName từ vựng.

Tôi nghĩ Saxon 9.3 bao gồm việc thực hiện bản xem trước của xpath 3.0 mà nên được sử dụng thông qua các api java.

+3

Chính xác, mặc dù 3.0 tính năng hiện tại chỉ có thể được bật trong phiên bản thương mại của sản phẩm. Các câu hỏi như "tại sao tính năng này không có trong các phiên bản trước" luôn khó trả lời - hoặc không ai đề xuất hoặc không đẩy mạnh đủ, hoặc họ phải cạnh tranh với các đề xuất của đối thủ để giải quyết cùng một vấn đề. –

0

Các spec cho XPath 3.0 nói:

Q{http://www.w3.org/2005/xpath-functions/math}pi 

này hoạt động tại thời điểm này (tháng 10 năm 2015) ví dụ như trong tồn tại-db.

+0

@ e4c5: XML thích sử dụng URI cho mọi thứ theo cú pháp của nó. Bạn nên đọc câu trả lời cẩn thận hơn. –

+0

@NathanTuggy có bạn đúng, trong khi kiểm duyệt đã xuất hiện như một liên kết chỉ trả lời (bình luận được tự động chèn bởi hệ thống) Tôi đã xóa bình luận đó. – e4c5

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