2011-08-04 41 views
10

Tôi cần tạo biểu thức XPath để lọc dựa trên thuộc tính có trong không gian tên đã cho. Ví dụ XML là:Lọc XPath trên thuộc tính với không gian tên

<feed xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' 
    xmlns:yt='http://gdata.youtube.com/schemas/2007'> ... 
<entry> 
    <media:group> 
    <media:thumbnail url='http://i.ytimg.com/1.jpg' yt:name='default'/> 
    <media:thumbnail url='http://i.ytimg.com/2.jpg' yt:name='hqdefault'/> 
    <media:thumbnail url='http://i.ytimg.com/3.jpg' yt:name='start'/> 
    <media:thumbnail url='http://i.ytimg.com/4.jpg' yt:name='middle'/> 
    </media:group> 
</entry> 

Và tôi cần nhận url của thuộc tính với tên thuộc tính yt: đặt thành 'hqdefault'.

Tôi đã thử với XPath biểu

'./media:group/media:thumbnail[@yt:name='hqdefault']/@url' 

nhưng có vẻ như xác định namespaced thuộc tính với yt: Tên không hoạt động. Tôi nhận được một DOMNodeList rỗng khi thực hiện một truy vấn.

tôi truy cập vào XML trong php, vì vậy tôi đã đăng ký yt namespace:

registerNamespace('yt', 'http://gdata.youtube.com/schemas/2007'); 

Thnx trước

+0

"không hoạt động" - bạn cần phải nói những gì xảy ra. Một thông báo lỗi? – LarsH

Trả lời

0

Tiền tố yt namespace được sử dụng trong ví dụ XML của bạn, nhưng không được công bố. Nếu ví dụ XML đó thực sự là tất cả, thì đó không phải là XML được định dạng đúng (trong các thuật ngữ không gian tên). Do đó, không có công cụ XML chung nào, như XSLT, có khả năng xử lý nó.

Mặt khác, nếu có khai báo tiền tố không gian tên yt ở đâu đó trong tài liệu nguồn mà bạn chưa hiển thị, thì bạn cần khai báo trong môi trường xử lý XPath của mình (XSLT tôi đoán) cùng một không gian tên URI. Ví dụ.

<xsl:stylesheet ... xmlns:yt="theNamespaceURIForYT"> 

XPath không biết bất kỳ khai báo tiền tố không gian tên nào xảy ra trong tài liệu nguồn. Nó chỉ biết những gì không gian tên (URI) mỗi phần tử (và thuộc tính) thuộc về.

+0

Tôi đã không nhập toàn bộ XML, xin lỗi. Đây là XML xuất XML của danh sách phát và bắt đầu bằng: ' ' tôi truy cập vào XML trong php, vì vậy tôi đã đăng ký yt namespace: ' registerNamespace ('yt', 'http://gdata.youtube.com/schemas/2007');' Nó không hoạt động có nghĩa là tôi nhận được một DOMNodeList rỗng khi thực hiện một truy vấn. Thnx – wurdalack

4

XPath đó có vẻ chính xác.

Có thể thư viện của bạn không hỗ trợ thuộc tính được đặt tên hoặc bạn chưa đăng ký đúng không gian tên yt và/hoặc không gian tên media.

Cố gắng chỉ phù hợp trên local-name()namespace-uri() bên trong bộ lọc ngữ, thay vì sử dụng namespace prefix-:

./*[local-name()='group' 
     and namespace-uri()='http://search.yahoo.com/mrss/' 
    ]/*[local-name()='thumbnail' 
     and namespace-uri()='http://search.yahoo.com/mrss/' 
     and @*[local-name()='name' 
       and namespace-uri()='http://gdata.youtube.com/schemas/2007' 
       and .='hqdefault' 
       ] 
     ]/@url 

Nếu công trình này, sau đó là một vấn đề đăng ký không gian tên cho những namespace- tiền tố.

1

Giả sử phần còn lại là theo thứ tự, chỉ đơn giản là thay thế các . đầu tiên trong xpath với / để có được //media:group/... (hoặc bắt đầu với /atom:feed/media:group/... và đăng ký tên miền không gian nguyên tử).

Dưới đây là một ví dụ làm việc hoàn chỉnh:

<?php 
$dom = new DOMDocument(); 
$dom->loadXML(<<<XML 
<feed xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' 
    xmlns:yt='http://gdata.youtube.com/schemas/2007'> 
    <entry> 
    <media:group> 
     <media:thumbnail url='http://i.ytimg.com/1.jpg' yt:name='default'/> 
     <media:thumbnail url='http://i.ytimg.com/2.jpg' yt:name='hqdefault'/> 
     <media:thumbnail url='http://i.ytimg.com/3.jpg' yt:name='start'/> 
     <media:thumbnail url='http://i.ytimg.com/4.jpg' yt:name='middle'/> 
    </media:group> 
    </entry> 
</feed> 
XML 
); 

$x = new DOMXPath($dom); 
$x->registerNamespace('yt', 'http://gdata.youtube.com/schemas/2007'); 
$x->registerNamespace('media', 'http://search.yahoo.com/mrss/'); 
$l= $x->query("//media:group/media:thumbnail[@yt:name='hqdefault']/@url"); 
for ($i=0; $i<$l->length; $i++) var_dump($l->item($i)->value); 
Các vấn đề liên quan