快速解析 XML 数据

Amo*_*s94 10 xml swift

这是我的第一个 iOS 应用程序,我在从 XML 获取数据时遇到了一些麻烦。我需要从如下所示的 XML 文件中获取歌曲名称和艺术家:

<?xml version="1.0" encoding="utf-8"?>
<Schedule System="Jazler">
  <Event status="happening" startTime="19:14:30" eventType="song">
    <Announcement Display="Now On Air:"/>
    <Song title="E timpul">
      <Artist name="Revers">
      </Artist>
      <Jazler ID="16490"/>
      <PlayLister ID=""/>
      <Media runTime="03:03"/>
      <Expire Time="19:17:33"/>
    </Song>
  </Event>
</Schedule>
Run Code Online (Sandbox Code Playgroud)

到目前为止,我认为我创建了解析器,但我不知道如何从中获取数据,而且在线教程让我有点困惑......

self.parser = XMLParser(contentsOf: URL(string:"http://localhost/jazler/NowOnAir.xml")!)!
self.parser.delegate = self as? XMLParserDelegate

let success:Bool = self.parser.parse()
if success {
    print("success")

} else {
    print("parse failure!")
}
Run Code Online (Sandbox Code Playgroud)

非常感谢您的帮助并提前致谢。

Rob*_*Rob 10

因为您的 XML 包含具有元素属性的所有值,所以您不需要实现foundCharacters. 只是didStartElement,例如,您的解析器委托可能看起来很简单:

var song: String?
var artist: String?

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
    switch elementName {
    case "Song":   song   = attributeDict["title"]
    case "Artist": artist = attributeDict["name"]
    default:       break
    }
}
Run Code Online (Sandbox Code Playgroud)

两个观察:

  1. 不过,我倾向于将此解析代码从视图控制器中提取出来,并将其放入专用对象中,以帮助防止“视图控制器膨胀”。

  2. URLSession如果对请求的响应碰巧有点慢,我也会使用。通常,应该避免使用XMLParser(contentsOf:),因为它会同步执行请求。

    在您的情况下,由于您是从 请求数据localhost,因此这可能不太重要。但是,始终异步执行 HTTP 请求仍然是明智的。

无论如何,这可能会产生类似的结果:

class SongParser: NSObject {
    var song: String?
    var artist: String?
    
    class func requestSong(completionHandler: @escaping (String?, String?, Error?) -> Void) {
        let url = URL(string: "http://localhost/jazler/NowOnAir.xml")!
        let task = URLSession.shared.dataTask(with: url) { data, _, error in
            guard let data = data, error == nil else {
                DispatchQueue.main.async {
                    completionHandler(nil, nil, error)
                }
                return
            }
            
            let delegate = SongParser()
            let parser = XMLParser(data: data)
            parser.delegate = delegate
            parser.parse()
            DispatchQueue.main.async {
                completionHandler(delegate.song, delegate.artist, parser.parserError)
            }
        }
        task.resume()
    }
}

extension SongParser: XMLParserDelegate {
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        switch elementName {
        case "Song":   song   = attributeDict["title"]
        case "Artist": artist = attributeDict["name"]
        default:       break
        }
    }
    
}
Run Code Online (Sandbox Code Playgroud)

你会像这样使用它:

SongParser.requestSong { song, artist, error in
    guard let song = song, let artist = artist, error == nil else {
        print(error ?? "Unknown error")
        return
    }
    
    print("Song:", song)
    print("Artist:", artist)
}
Run Code Online (Sandbox Code Playgroud)


Md.*_*afi 4

首先将你的xml转换成NSData并调用解析器来解析它。

//converting into NSData
var data: Data? = theXML.data(using: .utf8)

//initiate  NSXMLParser with this data
var parser: XMLParser? = XMLParser(data: data ?? Data())

//setting delegate
parser?.delegate = self

//call the method to parse
var result: Bool? = parser?.parse()

parser?.shouldResolveExternalEntities = true
Run Code Online (Sandbox Code Playgroud)

现在,您需要在您的类中实现 NSXMLParser 委托。

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
currentElement = elementName
print("CurrentElementl: [\(elementName)]")
}

func parser(_ parser: XMLParser, foundCharacters string: String) {
print("foundCharacters: [\(string)]")
}
Run Code Online (Sandbox Code Playgroud)

您将在 xml 的 key 下找到该值。