Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Jak ustawić przestrzeń nazw w SimpleXMLElement?
Forum PHP.pl > Forum > XML, AJAX > XML
Apocalyptiq
Robię właśnie mapę newsów pewnego serwisu dla Google News. Trzeba tam użyć przestrzeni nazw "news". Do wygenerowania takiej mapy xml używam oczywiście php, aby była dynamiczna. Do utworzenia mapy używam klasy SimpleXMLElement. Oto kod tego generatora:
  1. <?php require_once 'inc/db.php';
  2. header('Content-type: text/xml');
  3.  
  4. class SimpleXMLExtend extends SimpleXMLElement{
  5.    public function addCData($nodename,$cdata_text,$namespace=null){
  6.        $node = $this->addChild($nodename,null,$namespace); //Added a nodename to create inside the function
  7.        $node = dom_import_simplexml($node);
  8.        $no = $node->ownerDocument;
  9.        $node->appendChild($no->createCDATASection($cdata_text));
  10.    }
  11. }
  12.  
  13. $sitemap=new SimpleXMLExtend('<?xml version="1.0" encoding="utf-8"?><urlset xmlns="http://www.google.com/schemas/sitemap/0.84" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"/>');
  14.  
  15. $news=$db->getAll('SELECT * FROM news WHERE time>? ORDER BY time DESC LIMIT 20',(time()-60*60*24*3));
  16. foreach($news as $new){
  17.    $url=$sitemap->addChild('url');
  18.    $url->addCData('loc','http://www.elondyn.eu/news/'.$new['id']);
  19.    $news=$url->addChild('news',null,'news');
  20.    $news->addChild('publication_date',date('c',$new['time']),'news');
  21.    $keywords=explode(' ',$new['title']);
  22.    foreach($keywords as $i => $keyword){
  23.        # wywalenie jednoliterowych słów
  24.        if(mb_strlen($keyword,'utf-8')<2) unset($keywords[$i]);
  25.        # wywalenie znaków specjalnych
  26.        else $keywords[$i]=str_replace(array(':','!','(',')'),'',$keyword);
  27.    }
  28.    $news->addCData('keywords',implode(', ',$keywords),'news');
  29. }
  30.  
  31. echo $sitemap->asXML();
  32. ?>

Nakładka addCData dodaje mi <[CDATA[ ]]> - oznaczenie zawartości danego elementu jako tekst, który nie podlega walidacji (znaki &, < i > umieszczone w zawartości bez cdata wywalają błąd).

Nadając hamsko nazwę "news:news":
  1. <?php
  2. $news=$url->addChild('news:news');
  3. ?>

nie uzyskuje efektu - element ma nazwę "news". W dokumentacji funkcji AddChild znalazłem parametr odpowiadający za ową przestrzeń nazw, ale ustawiając go na "news":
  1. <?php
  2. $news=$url->addChild('news',null,'news');
  3. ?>

otrzymałem taki tag: <news xmlns="news">, a we wzorcu google jest <news:news> no i z tego co czytałem o tych przestrzeniach nazw, tak to właśnie powinno wyglądać. A dzieci elementu "news", którym też nadałem tą przestrzeń nazw, nie zmieniły się.

Następnie w funkcji konstruującej SimpleXMLElement znalazłem atrubuty "ns" i "is_prefix" - pierwszy to przestrzeń nazw, a drugi określa czy podana przestrzeń nazw to prefix (znalezione w komentarzach na php.net, przedostatni). Więc dałem w "ns" - "news" i "is_prefix" na true - że to prefix:
  1. $sitemap=new SimpleXMLExtend('<?xml version="1.0" encoding="utf-8"?><urlset xmlns="http://www.google.com/schemas/sitemap/0.84" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"/>',null,false,'news',true);

ale nadal nic się nie zmieniło ;/

Niby to xmlns:news nadaje już głównemu elementowi podczas tworzenia xmla:
  1. '<?xml version="1.0" encoding="utf-8"?><urlset xmlns="http://www.google.com/schemas/sitemap/0.84" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"/>'

ale widocznie w tym SimpleXMLElement trzeba jakoś inaczej to nadać.

A oto co uzyskuje.

Orientuje się ktoś jak to można uzyskać? :-)
Apocalyptiq
DZIĘKI! biggrin.gif
A jednak przestrzeni nazw identyfikuje sie po linkach, a nie nazwach :-) takie coś wypaliło:
  1. <?php
  2. $news=$url->addChild('news',null,'http://www.google.com/schemas/sitemap-news/0.9');
  3. ?>

DZIĘKI! ;-)
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.