使用 NSXMLParser 在 Swift 中解析 XML
Parsing XML in Swift with NSXMLParser
我要解析以下 XML 结构:
<plist version="1.0">
<dict>
<key>
PALABRA
</key>
<array>
<string>
CATEGORY
</string>
<string>
WORD
</string>
</array>
</dict>
</plist>
我正在使用 NSXMLParser 以这种方式解析 XML:
var posts = NSMutableArray()
var parser = NSXMLParser()
var elements = NSMutableDictionary()
var element = NSString()
var CATEGORY = NSMutableString()
var WORD = NSMutableString()
func parseXML() {
posts = []
parser = NSXMLParser(contentsOfURL:(NSURL(string:"http://www.serverbpw.com/cm/2016-1/hangman.php"))!)!
parser.delegate = self
parser.parse()
}
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
element = elementName
if (elementName as NSString).isEqualToString("array") {
elements = NSMutableDictionary()
elements = [:]
categoria = NSMutableString()
categoria = ""
}
if (elementName as NSString).isEqualToString("string") {
palabra = NSMutableString()
palabra = ""
}
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
if element.isEqualToString("string") {
categoria.appendString(string)
}
if element.isEqualToString("string") {
palabra.appendString(string)
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if (elementName as NSString).isEqualToString("array") {
if !categoria.isEqual(nil) {
elements.setObject(categoria, forKey: "CATEGORIA")
}
if !palabra.isEqual(nil) {
elements.setObject(palabra, forKey: "PALABRA")
}
posts.addObject(elements)
}
}
我从服务器获取的CATEGORY值是CATEGORY的内容,也是WORD的内容,而WORD的值只是WORD的内容。
我知道这不是解析 XML 的正确方法。问题是我不知道如何获取 CATEGORY 和 WORD 元素,因为它们具有相同的 ID ("String")。获取此信息的正确方法是什么?
服务器地址为:http://www.serverbpw.com/cm/2016-1/hangman.php
提前致谢!
这是一个 plist,因此您可以只使用 NSDictionary(contentsOfFile:)。
if let dict = NSDictionary(contentsOfFile: filePath) {
let array = dict["PALABRA"] as? [String]
let category = array?[0]
let word = array?[1]
}
如果您没有文件形式的数据,请使用此方法
if let dict = try NSPropertyListSerialization.propertyListWithData(xmlData, options: .Immutable, format: nil) as? NSDictionary {
//......
}
如果您要自己解析它,诀窍是您有两次出现 <string>
,您必须以某种方式区分它们。您可以拥有自己的计数器来跟踪哪个是哪个:
var posts: [[String: String]]!
var element: String!
var categoria: String?
var palabra: String?
var stringValue: String?
var counter: Int!
func parseXML(url: NSURL) {
posts = [[:]]
let parser = NSXMLParser(contentsOfURL: url)!
parser.delegate = self
parser.parse()
}
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
element = elementName
if elementName == "array" {
categoria = nil
palabra = nil
counter = 0
}
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
if element == "string" {
if stringValue == nil {
stringValue = string
} else {
stringValue! += string
}
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "string" {
stringValue = stringValue?.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
if counter == 0 {
categoria = stringValue
} else if counter == 1 {
palabra = stringValue
}
stringValue = nil
counter!++
}
if elementName == "array" {
var element = [String: String]()
if categoria != nil {
element["CATEGORIA"] = categoria
}
if palabra != nil {
element["PALABRA"] = palabra
}
posts.append(element)
}
}
但我同意 cezheng 的观点,这似乎是由 NSDictionary
plist 实现的,因此,您应该只使用 NSDictionary(contentsOfFile)
或您有什么。如果这真的是您正在构建的 XML,我会建议您使用不同的格式,例如:
<posts>
<post>
<category>
CATEGORY
</category>
<word>
WORD
</word>
</post>
</posts>
那么你就可以更容易地解析它,而不需要 counter
.
的愚蠢行为
我要解析以下 XML 结构:
<plist version="1.0">
<dict>
<key>
PALABRA
</key>
<array>
<string>
CATEGORY
</string>
<string>
WORD
</string>
</array>
</dict>
</plist>
我正在使用 NSXMLParser 以这种方式解析 XML:
var posts = NSMutableArray()
var parser = NSXMLParser()
var elements = NSMutableDictionary()
var element = NSString()
var CATEGORY = NSMutableString()
var WORD = NSMutableString()
func parseXML() {
posts = []
parser = NSXMLParser(contentsOfURL:(NSURL(string:"http://www.serverbpw.com/cm/2016-1/hangman.php"))!)!
parser.delegate = self
parser.parse()
}
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
element = elementName
if (elementName as NSString).isEqualToString("array") {
elements = NSMutableDictionary()
elements = [:]
categoria = NSMutableString()
categoria = ""
}
if (elementName as NSString).isEqualToString("string") {
palabra = NSMutableString()
palabra = ""
}
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
if element.isEqualToString("string") {
categoria.appendString(string)
}
if element.isEqualToString("string") {
palabra.appendString(string)
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if (elementName as NSString).isEqualToString("array") {
if !categoria.isEqual(nil) {
elements.setObject(categoria, forKey: "CATEGORIA")
}
if !palabra.isEqual(nil) {
elements.setObject(palabra, forKey: "PALABRA")
}
posts.addObject(elements)
}
}
我从服务器获取的CATEGORY值是CATEGORY的内容,也是WORD的内容,而WORD的值只是WORD的内容。 我知道这不是解析 XML 的正确方法。问题是我不知道如何获取 CATEGORY 和 WORD 元素,因为它们具有相同的 ID ("String")。获取此信息的正确方法是什么?
服务器地址为:http://www.serverbpw.com/cm/2016-1/hangman.php
提前致谢!
这是一个 plist,因此您可以只使用 NSDictionary(contentsOfFile:)。
if let dict = NSDictionary(contentsOfFile: filePath) {
let array = dict["PALABRA"] as? [String]
let category = array?[0]
let word = array?[1]
}
如果您没有文件形式的数据,请使用此方法
if let dict = try NSPropertyListSerialization.propertyListWithData(xmlData, options: .Immutable, format: nil) as? NSDictionary {
//......
}
如果您要自己解析它,诀窍是您有两次出现 <string>
,您必须以某种方式区分它们。您可以拥有自己的计数器来跟踪哪个是哪个:
var posts: [[String: String]]!
var element: String!
var categoria: String?
var palabra: String?
var stringValue: String?
var counter: Int!
func parseXML(url: NSURL) {
posts = [[:]]
let parser = NSXMLParser(contentsOfURL: url)!
parser.delegate = self
parser.parse()
}
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
element = elementName
if elementName == "array" {
categoria = nil
palabra = nil
counter = 0
}
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
if element == "string" {
if stringValue == nil {
stringValue = string
} else {
stringValue! += string
}
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == "string" {
stringValue = stringValue?.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
if counter == 0 {
categoria = stringValue
} else if counter == 1 {
palabra = stringValue
}
stringValue = nil
counter!++
}
if elementName == "array" {
var element = [String: String]()
if categoria != nil {
element["CATEGORIA"] = categoria
}
if palabra != nil {
element["PALABRA"] = palabra
}
posts.append(element)
}
}
但我同意 cezheng 的观点,这似乎是由 NSDictionary
plist 实现的,因此,您应该只使用 NSDictionary(contentsOfFile)
或您有什么。如果这真的是您正在构建的 XML,我会建议您使用不同的格式,例如:
<posts>
<post>
<category>
CATEGORY
</category>
<word>
WORD
</word>
</post>
</posts>
那么你就可以更容易地解析它,而不需要 counter
.