Reputation: 13
I have problem with XML parsing in Swift. I woul like to use AttributeDict
but i have many attributes to use it. So i use Dictionary
. But it's not working,
And i use code in this page:
Get attibuteDict of a subclass Xml parsing - Swift
but it's still not working. Tell me if you know My XML Data:
<root>
<day1><day1 p1.1="-" pk1.1="-" s1.1="" a1.1="-" p1.2="-" pk1.2="-" s1.2="" a1.2="-"
p1.3="Начертательная геометрия и компьютерная графика" pk1.3="НГиКГ" s1.3="Оспанова З. К."
a1.3="127 ГМК" p1.4="Начертательная геометрия и компьютерная графика" pk1.4="НГиКГ"
s1.4="Оспанова З. К." a1.4="127 ГМК" p1.5="Физика" pk1.5="Физика" s1.5="Сарсембаева Б. Д."
a1.5="913 ГУК" p1.6="Физика" pk1.6="Физика" s1.6="Сарсембаева Б. Д." a1.6="1035 с ГУК"
p1.7="Физика" pk1.7="Физика" s1.7="Сарсембаева Б. Д." a1.7="913а ГУК" p1.8="Физика"
pk1.8="Физика" s1.8="Сарсембаева Б. Д." a1.8="913а ГУК" p1.9="Физическая культура"
pk1.9="ФизКульт" s1.9="Акмалиев А. Ж." a1.9=" -" p1.10="Физическая культура" pk1.10="ФизКульт"
s1.10="Акмалиев А. Ж." a1.10=" -" p1.11="-" pk1.11="-" s1.11="" a1.11="-" p1.12="-" pk1.12="-"
s1.12="" a1.12="-" p2.1="-" pk2.1="-" s2.1="" a2.1="-" p2.2="Политология" pk2.2="Полит-ия"
s2.2="Анапияева Г. Б." a2.2="705 ГУК" p2.3="Физика" pk2.3="Физика" s2.3="Оспанов К. М."
a2.3="713 ГУК" p2.4="Физика" pk2.4="Физика" s2.4="Оспанов К. М." a2.4="713 ГУК"
p2.5="Начертательная геометрия и компьютерная графика" pk2.5="НГиКГ" s2.5="Оспанова З. К."
a2.5="1035в ГУК" p2.6="Начертательная геометрия и компьютерная графика" pk2.6="НГиКГ"
s2.6="Оспанова З. К." a2.6="1035в ГУК" p2.7="Физическая культура" pk2.7="ФизКульт" s2.7="Акмалиев А. Ж."
a2.7=" -" p2.8="Физическая культура" pk2.8="ФизКульт" s2.8="Акмалиев А. Ж." a2.8=" -" p2.9="-"
pk2.9="-" s2.9="" a2.9="-" p2.10="-" pk2.10="-" s2.10="" a2.10="-" p2.11="-" pk2.11="-" s2.11="" a2.11="-"
p2.12="-" pk2.12="-" s2.12="" a2.12="-" p3.1="-" pk3.1="-" s3.1="" a3.1="-" p3.2="-" pk3.2="-" s3.2="" a3.2="-"
p3.3="Математика II" pk3.3="Матем.II" s3.3="Акимжанова Ш. А." a3.3="713 ГУК" p3.4="Математика II"
pk3.4="Матем.II" s3.4="Акимжанова Ш. А." a3.4="713 ГУК" p3.5="Начертательная геометрия и компьютерная графика"
pk3.5="НГиКГ" s3.5="Иисова А. М." a3.5="533 ГУК" p3.6="Эдвайзер" pk3.6="ЭД" s3.6="Тирижанова М. Б."
a3.6="517 ВК" p3.7="Начертательная геометрия и компьютерная графика" pk3.7="НГиКГ" s3.7="Курманалиева Ш. М."
a3.7="805 ГУК" p3.8="Начертательная геометрия и компьютерная графика" pk3.8="НГиКГ" s3.8="Курманалиева Ш. М."
a3.8="805 ГУК" p3.9="Начертательная геометрия и компьютерная графика" pk3.9="НГиКГ" s3.9="Курманалиева Ш. М."
a3.9="708 ГУК" p3.10="Начертательная геометрия и компьютерная графика" pk3.10="НГиКГ"
s3.10="Курманалиева Ш. М." a3.10="708 ГУК" p3.11="-" pk3.11="-" s3.11="" a3.11="-" p3.12="-"
pk3.12="-" s3.12="" a3.12="-"></day1>
</day1>
</root>
And my not working Code:
@IBOutlet weak var tableView: UITableView!
func parser = NSXMLParser()
var schedule = NSDictionary()
var elements = NSMutableDictionary()
var element = NSString()
func beginParsing()
{
parser = NSXMLParser(contentsOfURL: NSURL(string: "SomeUrl")!)!
parser.delegate = self
parser.parse()
}
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: [NSObject : AnyObject]!)
{
element = elementName
if (elementName as NSString).isEqualToString("day1")
{
//name of subject
schedule = [p1.1="-", pk1.1="", s1.1="", a1.1="", p1.2="", pk1.2="",
s1.2="", a1.2="", p1.3="", pk1.3="", s1.3="",
a1.3="", p1.4="", pk1.4="",
s1.4="", a1.4="", p1.5="", pk1.5="", s1.5="",
a1.5="", p1.6="", pk1.6="", s1.6="", a1.6="",
p1.7="", pk1.7="", s1.7="", a1.7="", p1.8="",
pk1.8="", s1.8="", a1.8="", p1.9="",
pk1.9="", s1.9="", a1.9="", p1.10="", pk1.10="",
s1.10="", a1.10=""]
elements = NSMutableDictionary()
elements = [:]
}
}
func parser(parser: NSXMLParser!, foundCharacters string: NSString!)
{
if element.isEqualToString("day1") {
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName: String!, attributes: [NSObject : AnyObject]!) {
element = elementName
if (elementName as NSString).isEqual("day1") {
}
}
}
}
func parser(parser: NSXMLParser!, didEndElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!)
{
if (elementName as NSString).isEqualToString("day1") {
print(schedule)
}`
And i don't create this XML data, this XML data give me my university
Upvotes: 1
Views: 3276
Reputation: 6251
Use this class for Parse XML data with the help of SWXMLHash xml parser in Swift language.
https://github.com/drmohundro/SWXMLHash
import UIKit
public struct ParseMyXMLApis {
//MARK:- Parsing API here
public static func getparseMyApi(input: String, action:String, completion: (result: String, error: NSError?) -> Void) {
//Main API here
let is_URL: String = "Enter your url here"
let lobj_Request = NSMutableURLRequest(URL: NSURL(string: is_URL)!)
let session = NSURLSession.sharedSession()
lobj_Request.HTTPMethod = "POST"
lobj_Request.HTTPBody = input.dataUsingEncoding(NSUTF8StringEncoding)
//lobj_Request.addValue("www.cgsapi.com", forHTTPHeaderField: "Host")
lobj_Request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
lobj_Request.addValue(String(input.characters.count), forHTTPHeaderField: "Content-Length")
lobj_Request.addValue("http://tempuri.org/IService/\(action)", forHTTPHeaderField: "SOAPAction")
let task = session.dataTaskWithRequest(lobj_Request, completionHandler: {(data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
print("Response: \(response)")
// Checking here Response
if response != nil {
let statusCode = (response as! NSHTTPURLResponse).statusCode
print("Success: \(statusCode)")
// Checking here Response Status
if statusCode == 200 {
//Handling Data here
if data?.length > 0 {
let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
let xmls = SWXMLHash.parse(data!)
func enumerate(indexer: XMLIndexer, level: Int) {
for child in indexer.children {
let name:String? = child.element!.name
print("\(level) \(name)")
let text = child.element!.text
if text?.isEmpty == false{
print(text)
// Finish here Process
completion(result: text!, error: nil)
}
enumerate(child, level: level + 1)
}
}
enumerate(xmls, level: 0)
}else{
//Data nil Condition here
completion(result:"", error:error)
}
//Handling Error here
if error != nil
{
print("Error: " + error!.description)
completion(result:"", error:error)
}
}else{
//Invalid Status
print("Error: " + error!.description)
completion(result:"", error:error)
}
}else{
//Response Nil then handle here
print("Error: " + error!.description)
completion(result:"", error:error)
}
})
task.resume()
}
//MARK:- String To Dictionary Conversion
public func convertStringToDictionary(text: String) -> AnyObject! {
if let data = text.dataUsingEncoding(NSUTF8StringEncoding) {
do{
let json:AnyObject = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0))
return json
}catch{
print(error)
}
}
return nil
}
}
and Call this class
ParseMyXMLApis.getparseMyApi("Request here", action:"URL here", completion: { (result, error) -> Void in
if error != nil{
//Handel Error here
}else{
print("Result is here\(result)")
}
else
{
//Network Error Handling here
print("Couldn't connect to network")
}
}
Upvotes: 0
Reputation: 437432
A couple of observations:
Your didStartElement
should simply look at attributeDict
to get the attributes for an element.
You don't need a foundCharacters
method in this case, because you're only parsing elements tags, and not parsing anything between the open and close tags.
The foundCharacters
method, if you even needed it, shouldn't have a private didStartElement
implemented within it.
The only trick in your example is that you have very confusing XML with nested day1
tags. I'd really suggest changing the XML to something that makes sense.
But, if you're stuck with this, one fairly flexible solution is to keep a stack of element names (implemented as simple array, elementNames
), push an elementName
onto the stack in didStartElement
(by adding to the end of the array of elementNames
) and popping one off in didEndElement
(by calling removeLast
). So, for example, by the time you hit the inner day1
tag inside your XML, the array of elementNames
will be ["root", "day1", "day1"]
.
Now that you have that, you can check to see if you are looking at day1
inside another day1
by seeing if the last two items in elementNames
are both day1
.
For example:
func beginParsing(URL: NSURL) {
let parser = NSXMLParser(contentsOfURL: URL)!
parser.delegate = self
parser.parse()
print(schedule)
}
var schedule: [String: String]?
var elementNames = [String]()
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
elementNames.append(elementName)
let count = elementNames.count
if count >= 2 && elementNames[count - 2] == "day1" && elementNames[count - 1] == "day1" {
schedule = attributeDict
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
elementNames.removeLast()
}
func parser(parser: NSXMLParser, parseErrorOccurred parseError: NSError) {
print(parseError)
}
Upvotes: 3