Статьи

SimpleXML и пространства имен

Многое о SimpleXML , новом API-интерфейсе PHP5 для доступа к содержимому XML-документов, содержится в недавно опубликованной книге SitePoint « Никакая бессмысленная веб-разработка на XML с PHP» , но она не рассматривает одну вещь — как использовать SimpleXML с документом, который использует пространств имен XML .

Возьмем, к примеру, этот документ — упрощенный канал RSS 1.0:

<?xml version="1.0" encoding="utf-8"?> <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel rdf:about="http://www.sitepoint.com/"> <title>SitePoint.com</title> <link>http://www.sitepoint.com/</link> <description>SitePoint is the natural place to go to grow your online business.</description> <items> <rdf:Seq> <rdf:li rdf:resource="http://www.sitepoint.com/article/take-command-ajax" /> </rdf:Seq> </items> </channel> <item rdf:about="http://www.sitepoint.com/article/take-command-ajax"> <title>Take Command with AJAX</title> <link>http://www.sitepoint.com/article/take-command-ajax</link> <description>Want to get a bang out of your AJAX artillery?</description> <dc:date>2005-10-14T04:00:00Z</dc:date> </item> </rdf:RDF> 

В PHP5 вы можете подумать об использовании API SimpleXML для получения date каждого item в ленте:

 $feed = simplexml_load_file('http://www.sitepoint.com/recent.rdf'); foreach ($feed->item as $item) { echo $item->date; } 

Но это не сработает, поскольку элемент date имеет префикс пространства имен ( < dc: date> ), поэтому к нему нельзя получить доступ обычными средствами.

Вот решение. Сначала проверьте, что такое URI для пространства имен. В этом случае префикс dc: сопоставляется с URI http://purl.org/dc/elements/1.1/ :

 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/"> 

Затем используйте метод children объекта SimpleXML, передав ему этот URI:

 $feed = simplexml_load_file('http://www.sitepoint.com/recent.rdf'); foreach ($feed->item as $item) { $ns_dc = $item->children('http://purl.org/dc/elements/1.1/'); echo $ns_dc->date; } 

Когда вы передаете URI пространства имен методу children , вы получаете коллекцию SimpleXML дочерних элементов, принадлежащих этому пространству имен. Вы можете работать с этой коллекцией так же, как с любой коллекцией SimpleXML.

Вы можете использовать метод attributes таким же образом, чтобы получить атрибуты с префиксами пространства имен.