XML解析方式的选择建议
- 大文件用:NSXMLParser
- 小文件用:GDataXML
假设需要被解析的XML数据文件video.xml如下:
一,使用GDataXML(这个是google出品的)
- 在Build Phases -> Link Binary With Libraries中,点击“+”添加“libxml2.2.tbd”
在Build Setting -> Header Search Paths里添加
${SDK_DIR}/usr/include/libxml2
-
在Build Setting -> Other Linker Flags 里添加 -lxml2
在Build Phases里找到GDataXMLNode.m文件设置为非ARC(-fno-objc-arc)
- 添加bridge.h头文件并设置到编译参数里
#import "GDataXMLNode.h"
- 导入GDataXML库文件(GDataXMLNode.h和GDataXMLNode.m),代码结构如下:
- 开始解析(ViewController.swift)
import UIKit
import MediaPlayer
class VideosTableViewController: UITableViewController {
lazy var videos: NSMutableArray = {
return NSMutableArray()
}()
override func viewDidLoad() {
super.viewDidLoad()
/*
加载服务器最新的视频信息
*/
let urlStr = String(format: "http://localhost:8080/MJServer/video")
let url = NSURL(string: urlStr)
// 创建一个请求
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
// 设置请求体(参数)
let param = String(format: "type=%@", "XML")
// 设置字符串编码
request.HTTPBody = param.dataUsingEncoding(NSUTF8StringEncoding)
// 发送异步请求
let queue = NSOperationQueue.mainQueue()
NSURLConnection.sendAsynchronousRequest(request, queue: queue) { (request, data, error) -> Void in
if error != nil || data == nil {
MBProgressHUD.showError("网络繁忙")
return
}
// 加载整个XML数据
let doc = try! GDataXMLDocument(data: data!, options: 0)
// 获取文档的根节点
let root = doc.rootElement()
// 获得根节点里面所有的video元素
let elements = root.elementsForName("video") as! [GDataXMLElement]
// 遍历所有的video元素
for videoElement in elements {
let video: Video = Video()
// 取出元素的属性
video.id = videoElement.attributeForName("id").stringValue()
video.name = videoElement.attributeForName("name").stringValue()
video.image = videoElement.attributeForName("image").stringValue()
video.url = videoElement.attributeForName("url").stringValue()
video.length = videoElement.attributeForName("length").stringValue()
// 添加到数组中
self.videos.addObject(video)
}
self.tableView.reloadData()
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.videos.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let id = "video"
var cell = tableView.dequeueReusableCellWithIdentifier(id)
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: id)
}
let video = self.videos[indexPath.row] as! Video
cell?.textLabel?.text = video.name
cell?.detailTextLabel?.text = String(format: "时长: %d 分钟", video.length!)
let urlStr = String(format: "http://localhost:8080/MJServer/%@", video.image!)
let url = NSURL(string: urlStr)
// 这里使用了SDWebImage
cell?.imageView?.sd_setImageWithURL(url, placeholderImage: UIImage(named: "placehoder"))
return cell!
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// 取出对应的模型
let video = self.videos[indexPath.row] as! Video
// 创建系统提供的视频播放控制器
let videoUrl = String(format: "http://localhost:8080/MJServer/%@", video.url!)
let url = NSURL(string: videoUrl)
let playerVC = MPMoviePlayerViewController(contentURL: url)
// 显示播放器
self.presentViewController(playerVC, animated: true, completion: nil)
}
}
二,使用NSXMLParser
import UIKit
import MediaPlayer
class VideosTableViewController: UITableViewController, NSXMLParserDelegate {
lazy var videos: NSMutableArray = {
return NSMutableArray()
}()
override func viewDidLoad() {
super.viewDidLoad()
/*
加载服务器最新的视频信息
*/
let urlStr = String(format: "http://localhost:8080/MJServer/video")
let url = NSURL(string: urlStr)
// 创建一个请求
let request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = "POST"
// 设置请求体(参数)
let param = String(format: "type=%@", "XML")
// 设置字符串编码
request.HTTPBody = param.dataUsingEncoding(NSUTF8StringEncoding)
// 发送异步请求
let queue = NSOperationQueue.mainQueue()
NSURLConnection.sendAsynchronousRequest(request, queue: queue) { (request, data, error) -> Void in
if error != nil || data == nil {
MBProgressHUD.showError("网络繁忙")
return
}
// 1.创建XML解析器 -- SAX -- 逐个元素往下解析
let parser = NSXMLParser(data: data!)
// 2.设置代理
parser.delegate = self
// 3.开始解析(同步执行)
parser.parse()
self.tableView.reloadData()
}
}
/*****************************实现代理方法start***************************/
/**
解析到文档的开头时调用
*/
func parserDidStartDocument(parser: NSXMLParser) {
}
/**
解析到一个元素的开始就会调用
- parameter elementName: 元素名称
- parameter attributeDict: 属性字典
*/
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
if elementName == "videos" {
// 如果解析的是跟节点直接返回
return
}
// 解析到元素的时候,创建模型赋值
let video = Video(dict: attributeDict)
self.videos.addObject(video)
}
/**
解析到一个元素的结束就会调用
- parameter elementName: 元素名称
*/
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
}
/**
解析到文档的结尾时调用(解析结束)
*/
func parserDidEndDocument(parser: NSXMLParser) {
}
/*****************************实现代理方法end***************************/
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.videos.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let id = "video"
var cell = tableView.dequeueReusableCellWithIdentifier(id)
if cell == nil {
cell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: id)
}
let video = self.videos[indexPath.row] as! Video
cell?.textLabel?.text = video.name
cell?.detailTextLabel?.text = String(format: "时长: %d 分钟", video.length!)
let urlStr = String(format: "http://localhost:8080/MJServer/%@", video.image!)
let url = NSURL(string: urlStr)
cell?.imageView?.sd_setImageWithURL(url, placeholderImage: UIImage(named: "placehoder"))
return cell!
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// 取出对应的模型
let video = self.videos[indexPath.row] as! Video
// 创建系统提供的视频播放控制器
let videoUrl = String(format: "http://localhost:8080/MJServer/%@", video.url!)
let url = NSURL(string: videoUrl)
let playerVC = MPMoviePlayerViewController(contentURL: url)
// 显示播放器
self.presentViewController(playerVC, animated: true, completion: nil)
}
}