问题
I am trying to do XML Parsing of below file :
<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>
Basically I have created two ViewController, one for displaying Genre Title and second VC for displaying the details of this. For this, I have created below two Modal classes:
class GenreModel {
var title: String = ""
var genreSongsArray = [GenreSong]()
var genreSongs = GenreSong()
}
class GenreSong {
var songTitle: String = ""
var path: String = ""
}
Here is my code:
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) {
}
My problem is when I am giving "elementName == genre"
then it's only parsing genre title
and not parsing track details. How can I save both Genre title and Songs details in one custom Array?
Can anyone please suggest me on this? Thank you!
回答1:
You need to rethink your parsing strategy.
The XMLParser fires didStartElement
whenever a new element starts. So the first occurence is on the "genre" element.
The next two elements are "track" so the parser again fires didStartElement
for each of them.
It is your responsibility to keep track of the hierarchy so you need to store the current element in a variable and process the subelements.
So whenever you retrieve a new element with didStartElement
you have to check what element it is and what child elements you expect further. This all depends on the structure of your XML document so there is no all in one solution one can give you.
...
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
}
}
来源:https://stackoverflow.com/questions/52418876/how-to-do-xml-parsing-in-swift3-ios