Как сделать синтаксический анализ XML в Swift3 iOS? - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь выполнить синтаксический анализ XML для файла ниже:

<bgmusic>
  <genre title=“Title1”>
    <track title=“SubTitle1” path="https://test/Background_Track%20-%20Ambient%20-%20ANW2856_01_ Animation.ogg" />
    <track title="SubTitle2” path="https://test/Background_Track%20-%20Ambient%20-%20ANW2860_02_Entanglement.ogg" />
  </genre>

  <genre title="Title2”>
    <track title="SubTitle3” path="https://test/Background_Track%20-%20Ambient%20-%20ANW2856_01_Animate.ogg" />
    <track title="SubTitle4” path="https://test/Background_Track%20-%20Ambient%20-%20ANW2860_02_ SubTitle4.ogg" />
  </genre>

</bgmusic>

По сути, я создал два ViewController, один для отображения названия жанра и второй VC для отображения подробностей этого.Для этого я создал ниже два модальных класса:

class GenreModel {
    var title: String = ""

    var genreSongsArray = [GenreSong]()
    var genreSongs = GenreSong()
}

class GenreSong {
    var songTitle: String = ""
    var path: String = ""

}

Вот мой код:

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

       let genreModel = GenreModel()

        if(elementName == "genre"){

        if let id = attributeDict["title"] {
            genreModel.title = id
        }
       }

        if(elementName == "track")
        {
            let genreSong = GenreSong()
            for string in attributeDict {
                let strvalue = string.value as NSString
                switch string.key {
                case "title":
                    genreSong.songTitle = strvalue as String
                    break
                case "path":
                    genreSong.path = strvalue as String
                    break

                default:
                    break
                }
            }

            genreModel.genreSongsArray.append(genreSong)
        }
}

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

    }

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

    }

Моя проблема в том, что когда я даю "elementName == genre", тогда это только синтаксический анализ genre title и не анализирует детали дорожки.Как я могу сохранить название жанра и детали песни в одном пользовательском массиве?

Может кто-нибудь предложить мне это?Спасибо!

1 Ответ

0 голосов
/ 20 сентября 2018

Вам необходимо переосмыслить свою стратегию синтаксического анализа.

XMLParser запускает didStartElement всякий раз, когда запускается новый элемент.Таким образом, первый случай связан с элементом «жанр».

Следующие два элемента являются «треками», поэтому парсер снова запускает didStartElement для каждого из них.

Вы несете ответственность заследите за иерархией, поэтому вам нужно сохранить текущий элемент в переменной и обработать подэлементы.

Поэтому, когда вы получаете новый элемент с помощью didStartElement, вы должны проверить, что это за элемент и какие дочерние элементывы ожидаете дальше.Все зависит от структуры вашего XML-документа, поэтому нет единого решения, которое вы можете дать.

...
var genre = ""
var tracks = [String]()

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

    if(elementName == "genre") {
        // new genre
        tracks = []

        if let id = attributeDict["title"] {
            genre = id
        }
     }

     if(elementName == "track") {
        // new subElement track, add it to the tracks array here
     }
}

func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if(elementName == "genre") {
        // genre complete with all tracks, process it
    }
}
...