如何解析 Swift 中的 XML 附件
How do I parse XML enclosure in Swift
我正在编写一个 RSS 阅读器,它从 XML 标签收集信息并将它们放在 table 视图中。一切正常,但附件标签除外。我想捕获附件标签中包含的 url,这是一个 link 到我想播放的音频流。外壳标签看起来像这样
<enclosure url="http://www.podtrac.com/pts/redirect.mp3/bestradioyouhaveneverheard.com/media/floor_2015.mp3" type="audio/mpeg" length="76153214"/>
我搜索了整个示例,但只找到了 Objective C 个版本的解决方案。我无法弄清楚这一点。有人可以帮我吗?到目前为止,这是我的代码。
import UIKit
// Define the class for the table view
// ***********************************
class TableViewController: UITableViewController, NSXMLParserDelegate, UITableViewDataSource, UITableViewDelegate {
// Step 1 - Define the variables you will use
// ******************************************
var parser = NSXMLParser()
var feeds = NSMutableArray()
var elements = NSMutableDictionary()
var element = NSString()
var ftitle = NSMutableString()
var link = NSMutableString()
var fdescription = NSMutableString()
var currentList = String()
var feedEnclosure = NSMutableString()
var mystream = NSMutableString()
// Run these methods when the App Starts up
override func viewDidLoad() {
super.viewDidLoad()
// Step 2 - Setup the RSS Feed and Initialize the Parameters
// ********************************************************
feeds = []
var url = NSURL(string: "http://www.bestradioyouhaveneverheard.com/podcasts/index.xml")
var request = NSURLRequest(URL:url!)
parser = NSXMLParser (contentsOfURL: url)!
parser.delegate = self
parser.shouldProcessNamespaces = false
parser.shouldReportNamespacePrefixes = false
parser.shouldResolveExternalEntities = false
parser.parse()
}
// Step 3 - Define your Methods/Functions
// ***************************************
// Start Parsing and initialize variables to accept RSS data when <item> tag is encountered
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
element = elementName
if (element as NSString).isEqualToString("item") {
elements = NSMutableDictionary.alloc()
elements = [:]
ftitle = NSMutableString.alloc ()
ftitle = ""
link = NSMutableString.alloc()
link = ""
fdescription = NSMutableString.alloc()
fdescription = ""
feedEnclosure = NSMutableString.alloc()
feedEnclosure = ""
mystream = NSMutableString.alloc()
mystream = ""
}
}
// End Parsing Function and load dictionary key with <title> <link> and <itunes:summary> elements
func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
if (elementName as NSString).isEqualToString("item") {
if ftitle != "" {
elements.setObject(ftitle, forKey: "title")
//println(ftitle) // Lookey Loo
}
if (link != "") {
elements.setObject(link, forKey: "link")
//println(link) // Lookey Loo
}
if (fdescription != "") {
elements.setObject(fdescription, forKey: "itunes:summary")
//println(fdescription) // Lookey Loo
}
if (feedEnclosure != "") {
elements.setObject(feedEnclosure, forKey: "enclosure")
//println(mystream) // Lookey Loo
}
feeds.addObject(elements)
}
}
// Append the text from the element to the dictionary key location
func parser(parser: NSXMLParser!, foundCharacters string: String!) {
if element.isEqualToString("title"){
ftitle.appendString(string)
}else if element.isEqualToString("link"){
link.appendString(string)
}else if element.isEqualToString("itunes:summary"){
fdescription.appendString(string)
}else if element.isEqualToString("enclosure"){
mystream = attributeDict (valueForKey:@"url")
println(mystream)
}
}
// Now reload all the data
func parserDidEndDocument(parser: NSXMLParser!) {
self.tableView.reloadData()
}
// MARK ---> Define The Table View
//
// Define the number of sections in the tableview
//
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
// Define the number of rows to display based on the number of items loaded into the array feeds
//
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return feeds.count
}
// Populate the cell with data elements from parser Recycle the last cell
//
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
// Load an image file into the left margin
//
var image : UIImage = UIImage(named: "300px-banner.png")!
cell.imageView.image = image
// Load the parser data from the title element
//
cell.textLabel.text = feeds.objectAtIndex(indexPath.row).objectForKey ("title") as NSString
println(mystream)
// Load 3 lines of data for each cell
//
cell.textLabel.numberOfLines = 3
return cell
}
// Only grab the data at the selected cell
//
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
// Pass the data thru the segue
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!) {
if (segue.identifier == "mySegue") {
// Set the path of the Segue to the other view controller
//
let vc = segue.destinationViewController as secondViewController
// Set a constant to the current selected row
//
if let indexPath = self.tableView.indexPathForSelectedRow() {
// Create a constant to hold the data you want to pass to the other view controller
//
let currentList = feeds.objectAtIndex(indexPath.row).objectForKey("itunes:summary") as NSString
//println(currentList)
// let currentstream = feeds.objectAtIndex(indexPath.row).objectForKey("url") as NSString
// println(currentstream)
// Load that data into a segue parameter that passes thru the segue
//
vc.toPass = currentList
}
}
}
}
替换为:
if (feedEnclosure != "") {
elements.setObject(feedEnclosure, forKey: "enclosure")
//println(mystream) // Lookey Loo
}
为此:
if elementName == "enclosure" {
let attrsUrl = attributeDict as [String: NSString]
var urlPic = attrsUrl["url"]
elements.setObject(urlPic!, forKey: "enclosure")
}
我正在编写一个 RSS 阅读器,它从 XML 标签收集信息并将它们放在 table 视图中。一切正常,但附件标签除外。我想捕获附件标签中包含的 url,这是一个 link 到我想播放的音频流。外壳标签看起来像这样
<enclosure url="http://www.podtrac.com/pts/redirect.mp3/bestradioyouhaveneverheard.com/media/floor_2015.mp3" type="audio/mpeg" length="76153214"/>
我搜索了整个示例,但只找到了 Objective C 个版本的解决方案。我无法弄清楚这一点。有人可以帮我吗?到目前为止,这是我的代码。
import UIKit
// Define the class for the table view
// ***********************************
class TableViewController: UITableViewController, NSXMLParserDelegate, UITableViewDataSource, UITableViewDelegate {
// Step 1 - Define the variables you will use
// ******************************************
var parser = NSXMLParser()
var feeds = NSMutableArray()
var elements = NSMutableDictionary()
var element = NSString()
var ftitle = NSMutableString()
var link = NSMutableString()
var fdescription = NSMutableString()
var currentList = String()
var feedEnclosure = NSMutableString()
var mystream = NSMutableString()
// Run these methods when the App Starts up
override func viewDidLoad() {
super.viewDidLoad()
// Step 2 - Setup the RSS Feed and Initialize the Parameters
// ********************************************************
feeds = []
var url = NSURL(string: "http://www.bestradioyouhaveneverheard.com/podcasts/index.xml")
var request = NSURLRequest(URL:url!)
parser = NSXMLParser (contentsOfURL: url)!
parser.delegate = self
parser.shouldProcessNamespaces = false
parser.shouldReportNamespacePrefixes = false
parser.shouldResolveExternalEntities = false
parser.parse()
}
// Step 3 - Define your Methods/Functions
// ***************************************
// Start Parsing and initialize variables to accept RSS data when <item> tag is encountered
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!) {
element = elementName
if (element as NSString).isEqualToString("item") {
elements = NSMutableDictionary.alloc()
elements = [:]
ftitle = NSMutableString.alloc ()
ftitle = ""
link = NSMutableString.alloc()
link = ""
fdescription = NSMutableString.alloc()
fdescription = ""
feedEnclosure = NSMutableString.alloc()
feedEnclosure = ""
mystream = NSMutableString.alloc()
mystream = ""
}
}
// End Parsing Function and load dictionary key with <title> <link> and <itunes:summary> elements
func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!) {
if (elementName as NSString).isEqualToString("item") {
if ftitle != "" {
elements.setObject(ftitle, forKey: "title")
//println(ftitle) // Lookey Loo
}
if (link != "") {
elements.setObject(link, forKey: "link")
//println(link) // Lookey Loo
}
if (fdescription != "") {
elements.setObject(fdescription, forKey: "itunes:summary")
//println(fdescription) // Lookey Loo
}
if (feedEnclosure != "") {
elements.setObject(feedEnclosure, forKey: "enclosure")
//println(mystream) // Lookey Loo
}
feeds.addObject(elements)
}
}
// Append the text from the element to the dictionary key location
func parser(parser: NSXMLParser!, foundCharacters string: String!) {
if element.isEqualToString("title"){
ftitle.appendString(string)
}else if element.isEqualToString("link"){
link.appendString(string)
}else if element.isEqualToString("itunes:summary"){
fdescription.appendString(string)
}else if element.isEqualToString("enclosure"){
mystream = attributeDict (valueForKey:@"url")
println(mystream)
}
}
// Now reload all the data
func parserDidEndDocument(parser: NSXMLParser!) {
self.tableView.reloadData()
}
// MARK ---> Define The Table View
//
// Define the number of sections in the tableview
//
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
// Define the number of rows to display based on the number of items loaded into the array feeds
//
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return feeds.count
}
// Populate the cell with data elements from parser Recycle the last cell
//
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
// Load an image file into the left margin
//
var image : UIImage = UIImage(named: "300px-banner.png")!
cell.imageView.image = image
// Load the parser data from the title element
//
cell.textLabel.text = feeds.objectAtIndex(indexPath.row).objectForKey ("title") as NSString
println(mystream)
// Load 3 lines of data for each cell
//
cell.textLabel.numberOfLines = 3
return cell
}
// Only grab the data at the selected cell
//
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
}
// Pass the data thru the segue
override func prepareForSegue(segue: (UIStoryboardSegue!), sender: AnyObject!) {
if (segue.identifier == "mySegue") {
// Set the path of the Segue to the other view controller
//
let vc = segue.destinationViewController as secondViewController
// Set a constant to the current selected row
//
if let indexPath = self.tableView.indexPathForSelectedRow() {
// Create a constant to hold the data you want to pass to the other view controller
//
let currentList = feeds.objectAtIndex(indexPath.row).objectForKey("itunes:summary") as NSString
//println(currentList)
// let currentstream = feeds.objectAtIndex(indexPath.row).objectForKey("url") as NSString
// println(currentstream)
// Load that data into a segue parameter that passes thru the segue
//
vc.toPass = currentList
}
}
}
}
替换为:
if (feedEnclosure != "") {
elements.setObject(feedEnclosure, forKey: "enclosure")
//println(mystream) // Lookey Loo
}
为此:
if elementName == "enclosure" {
let attrsUrl = attributeDict as [String: NSString]
var urlPic = attrsUrl["url"]
elements.setObject(urlPic!, forKey: "enclosure")
}