作者:傲气战歌网 来源:www.27zg.com 发表时间:2014-03-24 03:02
Maybe you don't mind it looking like that, but now we'll see how to make it look nice, like the one I hand-coded, books.xml. We'll use tidy functions in PHP. These functions are not enabled by default (if I remember correctly).
<?php $tidy_options = array( 'input-xml' => true, 'output-xml' => true, 'indent' => true, 'wrap' => false, ); $tidy = new tidy(); $tidy->parseFile('books4.xml', $tidy_options); $tidy->cleanRepair(); echo $tidy; ?>This results in:
<?xml version="1.0"?> <books> <book isbn="978-1594489501"> <title>A Thousand Splendid Suns</title> <publisher>Riverhead Hardcover</publisher> <amazon_price>14.27</amazon_price> <author_firstname>Khaled</author_firstname> <author_lastname>Hosseini</author_lastname> </book> <book isbn="978-1594489587"> <title>The Brief Wondrous Life of Oscar Wao</title> <publisher>Riverhead Hardcover</publisher> <amazon_price>14.97</amazon_price> <author_firstname>Junot</author_firstname> <author_lastname>Diaz</author_lastname> </book> <book isbn="978-0545010221"> <title>Harry Potter and the Deathly Hallows</title> <publisher>Arthur A. Levine Books</publisher> <amazon_price>19.24</amazon_price> <author_firstname>J. K.</author_firstname> <author_lastname>Rowling</author_lastname> </book> </books>Much nicer...
You can also load a string instead using tidy::parseString(). You can see all the options here.
On the next page we'll create the RSS feed class which I promised you earlier.
Creating an RSS feed classI'll first give you the entire class. Then we'll talk a bit about it. I written comments many places which explain what the code is doing and we've been going through most of the functionality which is utilized in the class in the previous pages so I won't go into great detail explaining it.
<?php class RSSFeed { private $title; private $link; private $description; private $language; private $items = array(); private $dom; private $xpath; public function __construct($title, $link, $description, $language = 'en-us') { $this->set_title($title); $this->set_link($link); $this->set_description($description); $this->set_language($language); } public function add_item(array $data = array()) { if((array_key_exists('title', $data) && empty($data['title'])) || (array_key_exists('link', $data) && empty($data['link'])) || (array_key_exists('description', $data) && empty($data['description']))) { throw new Exception('Every item must have at least a title, link and description'); } if(array_key_exists('pubDate', $data) && !is_integer($data['pubDate'])) { throw new Exception('pubDate must be a UNIX timestamp'); } else if(array_key_exists('pubDate', $data) && is_integer($data['pubDate'])) { $data['pubDate'] = gmdate('D, j M Y H:i:s T', $data['pubDate']); } $this->items[] = $data; return $this; // enables chaining } // various "set" functions public function set_title($data) { $this->title = $data; } public function set_link($data) { $this->link = $data; } public function set_description($data) { $this->description = $data; } public function set_language($data) { $this->language = $data; } // various "get" functions public function get_title() { return $this->title; } public function get_link() { return $this->link; } public function get_description() { return $this->description; } public function get_language() { return $this->language; } public function parse($tidy = false, $tidy_options = null) { // create our DOM and XPath objects $this->dom = new DOMDocument(); $this->xpath = new DOMXPath($this->dom); $rss = $this->dom->createElement('rss'); $rss->setAttribute('version', '2.0'); // sorry, hardcoded - if you wish another version then you're out of luck $this->dom->appendChild($rss); // or, well... you could just change it $channel = $this->dom->createElement('channel'); // create the <channel> element $channel->appendChild($this->dom->createElement('title', $this->get_title())); // ... and add some children to it $channel->appendChild($this->dom->createElement('language', $this->get_language())); $channel->appendChild($this->dom->createElement('link', $this->get_link())); $channel->appendChild($this->dom->createElement('description', $this->get_description())); $rss->appendChild($channel); // finally append it to our root element (<rss>) // add the feeds foreach($this->items as $item) { $this->parse_item($item); } $xml = $this->dom->saveXML(); // generate XML // just in case somebody doesn't like the lack of newlines and indention in the generated output if(extension_loaded('tidy') && $tidy == true) { if(!is_array($tidy_options)) { $tidy_options = array( 'input-xml' => true, 'output-xml' => true, 'indent' => true, 'indent-cdata' => true, 'wrap' => false, ); } $tidy_options['input-xml'] = true; // MUST be true $tidy = new tidy(); $tidy->parseString($xml, $tidy_options); $tidy->cleanRepair(); return (string) $tidy; // by using typecasting we'll ensure it's a string and not an object that is returned } else { return $xml; } } private function parse_item($item) { $channel = $this->xpath->query('channel')->item(0); // first we'll retrieve the <channel> element $item_node = $this->dom->createElement('item'); // create our new element $channel->appendChild($item_node); // ... and append it to <channel> // create the children elements our <item> element foreach($item as $name => $value) { if(empty($value)) continue; // no use for empty tags if(strcasecmp($name, 'pubDate') == 0) $name = 'pubDate'; // ensure proper name. not pubdate or something else $f = $this->dom->createElement($name); switch($name) { default: $text_node = $this->dom->createTextNode($value); break; case 'description': $text_node = $this->dom->createCDATASection($value); break; } $f->appendChild($text_node); $item_node->appendChild($f); } } public function __toString() { return $this->parse(); } } header('Content-type: application/xml'); $rss = new RSSFeed('Test RSS Feed', 'http://localhost/rss_feed.php', 'Test RSS Feed generated using PHP DOM.'); $rss->add_item(array( 'title' => 'Test entry', 'link' => 'http://localhost/test.php?item=1', 'description' => 'First test item :)<br /><strong>Testing</strong>', 'pubDate' => mktime(12,0,0,12,18,2007), 'author' => 'Daniel', ))->add_item(array( 'title' => 'Second test entry', 'link' => 'http://localhost/test.php?item=2', 'description' => 'Second test item :D<br /><em>YAY ^_^</em>', 'pubDate' => mktime(11,38,22,10,17,2007), 'author' => 'Daniel', ))->add_item(array( 'title' => 'testing bla bla', 'link' => 'http://localhost/test.php?item=3', 'description' => 'just testing again. <code><?php echo "hello world"; ?>', 'pubDate' => mktime(11,11,35,10,15,2007), 'author' => 'Daniel', )); echo $rss->parse(true); ?>下一篇:常用RSS阅读器评测