Синтаксический анализ XML с RSS или веб-страницы. - PullRequest
1 голос
/ 03 апреля 2019

Мне нужно получить информацию с комического сайта, нет доступа к 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 голосов
/ 05 апреля 2019

Если вы не возражаете против использования внешней библиотеки для сопоставления, вы можете попробовать 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())
    }
}

Вы можетесопоставьте ваш XML, используя map(XMLString:) функцию класса XMLMapper, например:

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

Надеюсь, это поможет.

0 голосов
/ 03 апреля 2019

Используя другие методы с , вы можете выполнять итерации по этим узлам:

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

и получите титул и href, а также

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...