【问题标题】:XML parsing from RSS or web page从 RSS 或网页解析 XML
【发布时间】:2019-08-25 04:29:35
【问题描述】:

我需要从漫画相关网站获取信息,无法访问 JSON 解决方案,只能访问 XML。 该站点有一个“报亭”页面和一个 RSS“报亭”提要。 我正在尝试从两个来源解析信息。

使用 RSS 链接的问题: - 在 n°100 之后,我在控制台上获得了相同标签的两个单独的标题结果,但应该在同一行“Raccolta Zagor n°239”,而不是如下所示:

found title: Raccolta Zagor n
found title: °239
found link: https://www.sergiobonelli.it/scheda/39486/Raccolta-Zagor-n-238.html
adding: nil
  • 似乎无法填充数组,因此无法更新表格

使用页面链接的问题 - 无法解析页面,我不明白我是否可以解析这样的网页。

链接:

static let linkRSS = "https://www.sergiobonelli.it/rss.jsp?sezione=311"
static let linkNewstandFromWebPage = "https://www.sergiobonelli.it/sezioni/43/in-edicola"

我的帖子/漫画课:

class Post {

    var titolo : String
    var link : String


    init() {
        self.postTitle = ""
        self.link = ""
    }
}

我的解析器:

class XMLParserController: NSObject, XMLParserDelegate {

    var parser : XMLParser!

    var currentPost: Post?

    var posts : [Post] = []

    var currentTagParsed = ""

    var isParsingItem = false


    init(url: URL) {
        super.init()

        self.parser = XMLParser(contentsOf: url)!

        self.parser.delegate = self
    }




    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {


        if elementName == "item" {
            self.isParsingItem = true
            return
        }

        if self.isParsingItem == true {
            if elementName == "title" || elementName == "link" {
                self.currentTagParsed = elementName
            }
        }


    }



    func parser(_ parser: XMLParser, foundCharacters string: String) {


        if self.currentTagParsed == "title" {
            self.currentPost?.postTitle += string
            print("found title: \(string)")
        }

        if self.currentTagParsed == "link" {
            self.currentPost?.link += string
            print("found link: \(string)")
        }


    }



    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {

        self.currentTagParsed = ""

        if elementName == "item" {
            self.isParsingItem = false
            print("adding: \(String(describing: self.currentPost?.postTitle))")

            guard currentPost != nil else {return}
            self.posts.append(currentPost!)

            self.currentPost = Post.init()
        }


    }


}

我的控制器

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {



    @IBOutlet weak var myTable: UITableView!


    let parserController = XMLParserController.init(url: URL.init(string: AllLinks.linkRSS)!)


    override func viewDidLoad() {
        super.viewDidLoad()



        let resultFromClass = self.parserController.parser.parse()

        if resultFromClass == true {
            self.myTable.reloadData()
            print(resultFromClass)
        }

        print("items count: \(parserController.posts.count)")

    }



    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return parserController.posts.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)

        cell.textLabel?.text = parserController.posts[indexPath.row].postTitle

        return cell
    }



}

【问题讨论】:

    标签: swift xml xml-parsing html-parsing


    【解决方案1】:

    使用 的其他方法,您可以在此节点上进行迭代:

    '//a[starts-with(@href, "https://shop.sergiobonelli.it")]'
    

    同时获取标题和 href

    【讨论】:

    • 我不明白如何准确地使用您的代码,但我需要显示 href,我认为当用户点击单元格以获取更多详细信息时,最终会使用它。此时我需要更好地利用解析器。
    • 搜索xpath的使用方法
    【解决方案2】:

    如果您不介意使用外部库进行映射,可以尝试XMLMapper

    使用以下模型:

    class RSSFeed: XMLMappable {
        var nodeName: String!
    
        var channel: Channel?
    
        required init?(map: XMLMap) {}
    
        func mapping(map: XMLMap) {
            channel <- map["channel"]
        }
    }
    
    class Channel: XMLMappable {
        var nodeName: String!
    
        var title: String?
        var link: String?
        var description: String?
        var image: Image?
        var atomLink: AtomLink?
        var items: [Item]?
    
        required init?(map: XMLMap) {}
    
        func mapping(map: XMLMap) {
            title <- map["title"]
            link <- map["link"]
            description <- map["description"]
            image <- map["image"]
            atomLink <- map["atom:link"]
            items <- map["item"]
        }
    }
    
    class Image: XMLMappable {
        var nodeName: String!
    
        var url: URL?
        var title: String?
        var link: URL?
    
        required init?(map: XMLMap) {}
    
        func mapping(map: XMLMap) {
            url <- (map["url"], XMLURLTransform())
            title <- map["title"]
            link <- (map["link"], XMLURLTransform())
        }
    }
    
    class AtomLink: XMLMappable {
        var nodeName: String!
    
        var href: URL?
        var rel: String?
        var type: String?
    
        required init?(map: XMLMap) {}
    
        func mapping(map: XMLMap) {
            href <- (map.attributes["href"], XMLURLTransform())
            rel <- map.attributes["rel"]
            type <- map.attributes["type"]
        }
    }
    
    class Item: XMLMappable {
        var nodeName: String!
    
        static let dateFormatter: DateFormatter = {
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "E, dd MMM yyyy HH:mm:ss zzz"
            return dateFormatter
        }()
    
        var title: String?
        var link: URL?
        var guid: URL?
        var description: String?
        var pubDate: Date?
        var mediaContent: MediaContent?
        var category: String?
    
        required init?(map: XMLMap) {}
    
        func mapping(map: XMLMap) {
            title <- map["title"]
            link <- (map["link"], XMLURLTransform())
            guid <- (map["guid"], XMLURLTransform())
            description <- map["description"]
            pubDate <- (map["pubDate"], XMLDateFormatterTransform(dateFormatter: Item.dateFormatter))
            mediaContent <- map["media:content"]
            category <- map["category"]
        }
    }
    
    class MediaContent: XMLMappable {
        var nodeName: String!
    
        var url: URL?
        var mediaThumbnail: MediaThumbnail?
    
        required init?(map: XMLMap) {}
    
        func mapping(map: XMLMap) {
            url <- (map.attributes["url"], XMLURLTransform())
            mediaThumbnail <- map["media:thumbnail"]
        }
    }
    
    class MediaThumbnail: XMLMappable {
        var nodeName: String!
    
        var url: URL?
    
        required init?(map: XMLMap) {}
    
        func mapping(map: XMLMap) {
            url <- (map.attributes["url"], XMLURLTransform())
        }
    }
    

    您可以使用XMLMapper 类的map(XMLString:) 函数映射您的XML,例如:

    let rssFeed = XMLMapper<RSSFeed>().map(XMLString: xmlString)
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-03-28
      • 1970-01-01
      • 2012-01-04
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      • 2021-02-15
      • 1970-01-01
      相关资源
      最近更新 更多