2012-11-04 31 views
5
$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/'); 

Từ những gì tôi hiểu chúng hoạt động như định nghĩa tài liệu và được yêu cầu xác định các yếu tố XML nhất định.Các không gian tên DomDocument là gì?

PHP thực sự có yêu cầu URL đó và xác minh xem phần tử có tồn tại trong định nghĩa tài liệu không?

Bởi vì URL cho thấy một trang 404 not found :(

$result = $xpath->evaluate('string(//atom:entry[3]/slash:comments)'); 

Phải chăng đây là lý do tại sao tôi nhận được một chuỗi rỗng, trong khi cố gắng để lấy giá trị của phần tử <slash> từ một RSS feed?

Trả lời

5
$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/'); 

Từ những gì tôi hiểu chúng hoạt động giống như định nghĩa tài liệu, và được yêu cầu phải xác định các yếu tố XML nhất định.

PHP thực sự có yêu cầu URL đó và xác minh xem phần tử có tồn tại trong định nghĩa tài liệu không?

số
Đó URI xác định một XML namespace, đại diện cho một từ vựng XML. Các không gian tên như vậy được thiết kế để đối phó với các ngữ cảnh khác nhau sử dụng cùng một thuật ngữ với các ý nghĩa khác nhau. Với các không gian tên, một tệp XML duy nhất có thể chứa các thẻ và thuộc tính với cùng một "tên", có đủ điều kiện thông qua một tiền tố. Ví dụ, bạn có thể có một tài liệu xml như thế này:

<html xmlns="http://www.w3.org/1999/xhtml" 
     xmlns:human="http://sample.xml.com/Human"> 
    <title>John Smith measures.</title> 
    <body> 
    <human:name>John</human:name> <human:surname>Smith</human:surname> 
    is <human:height unit="feet">6</human:height> feet tall. 
    </body> 
</html> 

Trong nội dung đó tiền tố "con người" được sử dụng để đánh dấu các yếu tố từ namespace http://sample.xml.com/Human và chuỗi rỗng (có nghĩa là tiền tố mặc định) được sử dụng để đánh dấu các yếu tố từ không gian tên http://www.w3.org/1999/xhtml. URI này là số nhận dạng không gian tên, không phải là vị trí lược đồ (có thể được biểu thị bằng DOCTYPE declaration hoặc XML Schema instance). Đó là một thực hành tốt để cung cấp tài liệu thích hợp về không gian tên tại vị trí được xác định bởi không gian tên URI, nhưng không bắt buộc (thực sự là không gian tên xhtml URI trỏ đến tài liệu W3C liên quan, nhưng phần mở rộng RSS bạn đang tìm kiếm, không) .

Lưu ý tuy nhiên rằng cả hai resolveExternalsvalidateOnParse có thể ảnh hưởng đến việc tải các DTD hoặc định nghĩa lược đồ giới thiệu bởi xml mục tiêu, nhưng không tài liệu namespace. Không có nghĩa là, bất kỳ trình phân tích cú pháp nào cũng sẽ tải xuống một tài liệu như vậy, vì nó dành cho mục đích sử dụng của con người.

$result = $xpath->evaluate('string(//atom:entry[3]/slash:comments)'); 

Phải chăng đây là lý do tại sao tôi nhận được một chuỗi rỗng, trong khi cố gắng lấy giá trị của các phần tử từ một RSS feed?

số
Đầu tiên, hãy kiểm tra xml nguồn chứa xmlns tờ khai chính xác và rằng nó chứa một <slash:comments> nút bên thứ ba nhập nguyên tử (lưu ý, thứ ba, bởi vì xpath lập chỉ mục là một dựa trên, để //atom:entry[1] có nghĩa là mỗi mục nhập là mục nhập đầu tiên trong nút cha của chính nó, //atom:entry[2] giây thứ hai và tiếp tục).
Nếu vậy, tôi nghi ngờ rằng bạn đã quên đăng ký không gian tên nguyên tử.
Hãy thử một cái gì đó như thế này (chuyển thể từ đóng góp của người sử dụng để DOMXPath::registerNamespace tài liệu):

$doc = new DOMDocument; 
$doc->loadXML($xml); // your xml string here 
$xpath = new DOMXPath($doc); 

$xpath->registerNamespace('atom', "http://www.w3.org/2005/Atom"); 
$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/'); 

$result = $xpath->evaluate('string(//atom:entry[3]/slash:comments)'); 

Bạn có thể thấy điều này chạy ở http://codepad.org/JX8RpaKu

Thật vậy, để sử dụng XPath đủ điều kiện, bạn cần đăng ký gian tên mặc định quá.

1

Nếu bạn muốn để lấy nội dung của các nút namespaced, bạn đã thử getElementsByTagNameNS?

$dom - new DOMDocument($url); 
$slashEls = $dom->getElementsbyTagNameNS('slash', 'slash'); // Assuming the element is <slash:slash> in the XML 
foreach($slashEls as $slash) { 
    // ... 
} 
+0

nó trả về một DOMNodeList trống ... –

2

Bạn có nhiều câu hỏi. Tôi sẽ cố gắng để giải quyết từng cái một:

$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/'); 

Từ những gì tôi hiểu chúng hoạt động giống như định nghĩa tài liệu, và được yêu cầu phải xác định các yếu tố XML nhất định.

Có, bất cứ khi nào bạn có tài liệu XML với không gian tên, thì mỗi phần tử có thể nằm trong không gian tên riêng của nó.

Nếu bạn muốn truy cập các phần tử trong vùng tên riêng của chúng, thì có, bạn cần không gian tên để nhận dạng chúng. Ví dụ. trong biểu thức Xpath.

Trong PHP không gian tên XML được hỗ trợ bởi DOMDocument và các phần mở rộng XML dựa trên libxml khác.

PHP thực sự có yêu cầu URL đó và xác minh xem phần tử có tồn tại trong định nghĩa tài liệu không?

Không, vì các mã ví dụ bạn đưa ra:

$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/'); 

PHP sẽ không yêu cầu URL đó. Bạn đã nhận thấy rằng URL trống/cung cấp 404 để bạn có thể muốn hiểu điều này là gì. URL đó trên thực tế là một URI. Đó là sự khác biệt và Mã định danhĐịnh vị.

The URI Pill: Can be URL or URN

Để có không gian tên XML làm việc, không có gì cần phải được bố trí. Không gian tên chỉ cần được xác định. Do đó, một không gian tên XML hợp lệ có thể được biểu diễn bằng bất kỳ URI nào. Ví dụ, fantasy:space là một URI hợp lệ và hoàn toàn đủ điều kiện các yêu cầu để chỉ định một không gian tên XML. Nhưng khi bạn nhập nó vào trình duyệt, bạn thậm chí sẽ không nhận được bất kỳ phản hồi nào của máy chủ (trình duyệt của bạn không biết "tưởng tượng" là gì).

Vì vậy, 404 bạn nhận được không phải là lý do tại sao các dấu gạch chéo là trống với đánh giá XPath của bạn:

$result = $xpath->evaluate('string(//atom:entry[3]/slash:comments)'); 

Lý do tại sao bạn nhận được một chuỗi rỗng đây là một trong những khác nhau. Xem biểu thức Xpath:

string(//atom:entry[3]/slash:comments) 

Đó là yêu cầu giá trị chuỗi của tập hợp nút. Bạn đã xác định các nút thiết lập như:

//atom:entry[3]/slash:comments 

Getting a string of a nodeset trong PHP DOMDocument có nghĩa là:

Một nút-bộ được chuyển thành một chuỗi bằng cách trả lại string-value of the node trong nút-bộ đó là lần đầu tiên trong thứ tự tài liệu. Nếu tập hợp nút trống, một chuỗi rỗng sẽ được trả về.

Khi nút là một yếu tố, chuỗi giá trị của the element node có nghĩa là:

Chuỗi giá trị của một nút phần tử là nối của chuỗi giá trị của tất cả các hậu duệ nút văn bản của nút phần tử trong thứ tự tài liệu.

Vì vậy, có hai cách giải thích tại sao bạn nhận được chuỗi rỗng: Tập hợp nút trống hoặc giá trị chuỗi thành phần chỉ là một chuỗi rỗng.

Bạn có thể nhanh chóng tìm hiểu về số lượng các nút bên trong một nút thiết lập bằng cách sử dụng các count() function:

$result = $xpath->evaluate('count(//atom:entry[3]/slash:comments)'); 

Mà sau đó sẽ cho bạn một ý tưởng tốt hơn nào trong hai trường hợp là như vậy. Vì bạn chưa chia sẻ XML nguồn nên không thể nói được lý do tại sao đặc biệt là nó - như tôi sẽ giả định - không chứa nút nào. Nhìn thấy nguồn nên làm rõ điều này một cách dễ dàng.

Cho đến lúc đó, tôi chỉ có thể đoán rằng bạn có thể phân tích cú pháp nguồn cấp dữ liệu RSS 2 không chứa các yếu tố <atom:entry> nhưng chỉ <item> yếu tố. Xem ví dụ của tôi:

$feed = 'http://hakre.wordpress.com/feed/'; 

$doc = new DOMDocument(); 
$doc->load($feed); 
$xpath = new DOMXPath($doc); 

echo $xpath->evaluate('string(//item[3]/slash:comments)'); # 1 

Nó xuất ra giá trị "1" làm số nhận xét cho mục thứ ba. Đây là nguồn cấp dữ liệu của một blog Wordpress chuẩn. I have put this online as an interactive example, so you can see it in action and enter your feed URL.

BTW: Nếu bạn tạo các đối tượng DOMXPathsau bạn đã nạp XML, bạn không cần phải đăng ký tên miền không gian-URI miễn là bạn biết được các tiền tố được sử dụng trong tài liệu. Đây là lý do tại sao trong ví dụ này tôi không đăng ký bất kỳ không gian tên-URI nào.

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