如何解析 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")
}