2010-06-16 2 views
1

быстрый вопрос: мне нужно преобразовать структуру RSS по умолчанию в другой XML-формат.Преобразование RSS-канала в другой «стандартный» XML-формат с PHP

RSS-файла, как ....

<?xml version="1.0" encoding="UTF-8"?> 
    <rss version="2.0"> 
     <channel> 
      <title>Name des RSS Feed</title> 
      <description>Feed Beschreibung</description> 
      <language>de</language> 
      <link>http://xml-rss.de</link> 
      <lastBuildDate>Sat, 1 Jan 2000 00:00:00 GMT</lastBuildDate> 
      <item> 
       <title>Titel der Nachricht</title> 
       <description>Die Nachricht an sich</description> 
       <link>http://xml-rss.de/link-zur-nachricht.htm</link> 
       <pubDate>Sat, 1. Jan 2000 00:00:00 GMT</pubDate> 
       <guid>01012000-000000</guid> 
      </item> 
      <item> 
       <title>Titel der Nachricht</title> 
       <description>Die Nachricht an sich</description> 
       <link>http://xml-rss.de/link-zur-nachricht.htm</link> 
       <pubDate>Sat, 1. Jan 2000 00:00:00 GMT</pubDate> 
       <guid>01012000-000000</guid> 
      </item> 
      <item> 
       <title>Titel der Nachricht</title> 
       <description>Die Nachricht an sich</description> 
       <link>http://xml-rss.de/link-zur-nachricht.htm</link> 
       <pubDate>Sat, 1. Jan 2000 00:00:00 GMT</pubDate> 
       <guid>01012000-000000</guid> 
      </item> 
     </channel> 
    </rss> 

... и я хочу, чтобы извлечь только элемент-элементы (с Чайлдс и атрибуты) XML, как:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<item> 
    <title>Titel der Nachricht</title> 
    <description>Die Nachricht an sich</description> 
    <link>http://xml-rss.de/link-zur-nachricht.htm</link> 
    <pubDate>Sat, 1. Jan 2000 00:00:00 GMT</pubDate> 
    <guid>01012000-000000</guid> 
</item> 
... 

It не должен храниться в файле. Мне нужен только результат.

Редактировать: Кроме того, вам необходимо знать: в файле RSS может быть динамическое количество элементов. Это всего лишь образец. Поэтому он должен быть зациклен с while, for, for-each, ...

Я пробовал разные подходы с DOMNode, SimpleXML, XPath, ... но безуспешно.

Благодаря Криса

+0

Я отправил ответ ниже упаковывают вы не заметили. Он должен объяснить все: o) – vimist

ответ

1

Другой подход будет использовать XSLT:

$xsl = <<< XSL 
<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="/"> 
<items> 
    <xsl:copy-of select="//item"> 
    <xsl:apply-templates/> 
    </xsl:copy-of> 
</items> 
</xsl:template> 
</xsl:stylesheet> 
XSL; 

выше таблицы стилей имеет только одно правило, а именно глубокое копирование всех <item> элементов из исходного XML в файл XML и игнорировать все остальное от источника файл. Узлы будут скопированы в элемент <items> для корневого узла. Чтобы обработать это, вы бы сделали

$xslDoc = new DOMDocument();   // create Doc for XSLT 
$xslDoc->loadXML($xsl);    // load stylesheet into it 
$xmlDoc = new DOMDocument();   // create Doc for RSS 
$xmlDoc->loadXML($xml);    // load your XML/RSS into it 
$proc = new XSLTProcessor();   // init XSLT engine 
$proc->importStylesheet($xslDoc);  // load stylesheet into engine 
echo $proc->transformToXML($xmlDoc); // output transformed XML 

Вместо вывода вы могли просто написать возвращаемое значение в файл.

Дальнейшее чтение:

+0

Я попробую завтра и дам вам обратную связь. не думал о подходе xslt - благодаря этому! – ChrisBenyamin

+0

Эй, Гордон, где мне включить (или ссылку) в мой данный RSS-файл? Я спрашиваю, потому что в PHP-части вы написали в четвертом комментарии «загрузите xml/rss», но var $ xml уже используется для XSL выше. - XSL - это довольно новый материал для меня, поэтому, я думаю, я все еще думаю слишком сложно. Редактировать: Хорошо, я слепой или все еще устал. Я не видел, есть два разных vars ($ xml и $ xsl). - давайте попробуем;) – ChrisBenyamin

+0

@Chris вы можете назначить '$ xml' var так же, как вы присваиваете' $ xsl' синтаксисом HEREDOC. Или используйте '-> load ('filename.xml')'. – Gordon

0

Try:

<?php 
$xmlFile = new DOMDocument(); //Instantiate new DOMDocument 
$xmlFile->load("URL TO RSS/XML FILE"); //Load in XML/RSS file 
$xmlString = file_get_contents("URL TO RSS/XML FILE"); 

$title[] = ""; 
$description[] = ""; 
$link[] = ""; 
$pubDate[] = ""; 
$guid[] = ""; 

for($i = 0; $i < substr_count($xmlString, "<item>"); $i++) 
{ 
$title[] = $xmlFile->getElementsByTagName("title")->item(0)->nodeValue; //Get the value of the node <title> 
$description[] = $xmlFile->getElementsByTagName("description")->item(0)->nodeValue; 
$link[] = $xmlFile->getElementsByTagName("link")->item(0)->nodeValue; 
$pubDate[] = $xmlFile->getElementsByTagName("pubDate")->item(0)->nodeValue; 
$guid[] = $xmlFile->getElementsByTagName("guid")->item(0)->nodeValue; 
} 
?> 

непроверенные, но массивы

$ Название [] $ Описание [] $ ссылки [] $ PubDate [] $ справы []

должно быть заполнено всеми данными t шляпа тебе нужна!

EDIT: ИТАК другой подход:

<?php 
$xmlString = file_get_contents("URL TO RSS/XML FILE"); 
$titles = preg_filter("/<title>([.]*)</title>/","\\1", mixed $xmlString); 
$descriptions = preg_filter("/<description>([.]*)</description>/","\\1", mixed $xmlString); 
$links = preg_filter("/<link>([.]*)</link>/","\\1", mixed $xmlString); 
$pubDates = preg_filter("/<pubDate>([.]*)</pubDate>/","\\1", mixed $xmlString); 
$guids = preg_filter("/<guid>([.]*)</guid>/","\\1", mixed $xmlString); 
?> 

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

+0

был бы вам, если бы вы могли расширить свой подход. спасибо – ChrisBenyamin

+0

спасибо cheif17, но это не кажется мне чистым решением для подобных проблем. с вашим кодом вам нужно подобрать каждый атрибут и создать новый XML-документ с помощью массивов. – ChrisBenyamin

+0

ОК, я сделал редактирование внизу с совершенно другим подходом! – vimist

1

То, о чем вы просите, вряд ли является трансформацией. Вы в основном просто извлекаете элементы <item>, как есть. Кроме того, результат, который вы даете, недействителен XML, поскольку ему не хватает корневого узла.

Кроме того, вы можете просто сделать это следующим образом:

$dom = new DOMDocument;   // init new DOMDocument 
$dom->loadXML($xml);    // load some XML into it 

$xpath = new DOMXPath($dom);  // create a new XPath 
$nodes = $xpath->query('//item'); // Find all item elements 
foreach($nodes as $node) {  // Iterate over found item elements 
    echo $dom->saveXml($node); // output the item node outerHTML 
} 

выше будет вторить <item> узлов. Вы можете просто буферизовать вывод, объединить его в строку, записать в нее массив и вставить, и т.д. - и записать его в файл.

Если вы хотите, чтобы сделать это правильно с DOM (и корневой узел), полный код будет выглядеть так:

$dom = new DOMDocument;       // init DOMDocument for RSS 
$dom->loadXML($xml);        // load some XML into it 

$items = new DOMDocument;      // init DOMDocument for new file 
$items->preserveWhiteSpace = FALSE;    // dump whitespace 
$items->formatOutput = TRUE;      // make output pretty 
$items->loadXML('<items/>');      // create root node 

$xpath = new DOMXPath($dom);      // create a new XPath 
$nodes = $xpath->query('//item');    // Find all item elements 
foreach($nodes as $node) {      // iterate over found item nodes 
    $copy = $items->importNode($node, TRUE);  // deep copy of item node 
    $items->documentElement->appendChild($copy); // append item nodes 
} 
echo $items->saveXML();       // outputs the new document 

Вместо saveXML(), вы бы использовать save('filename.xml'), чтобы записать его в файл.

+0

спасибо, гордон, хорошо выглядит, но я получаю сообщение об ошибке. не смог выяснить, что такое неудача. «Предупреждение: DOMDocument :: loadXML() [domdocument.loadxml]: начальный тег ожидается, '<' не найден в Entity, строка: 1 в /home/chris/http/dev/xmlfeed/index3.php в строке 4" – ChrisBenyamin

+0

@Chris Я использовал XML-XML, который вы указали для $ xml. Помните, loadXML загружается из String. Если вы хотите загрузить из URL или файла, используйте load(). – Gordon

+0

ничего себе это сладкое. спасибо и спокойной ночи (CET, 0: 16h) – ChrisBenyamin