从RSS或网页进行XML解析

时间:2019-04-03 15:16:06

标签: swift xml xml-parsing html-parsing

我需要从与漫画相关的网站上获取信息,不能访问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
    }



}

2 个答案:

答案 0 :(得分:0)

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

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

并获得标题和href

答案 1 :(得分:0)

如果您不介意使用外部库进行映射,则可以尝试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())
    }
}

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

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

希望这会有所帮助。

相关问题