12076

Swift XML attribute parsing

Question:

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:

<a href="https://stackoverflow.com/questions/30820024/get-attibutedict-of-a-subclass-xml-parsing-swift" rel="nofollow">Get attibuteDict of a subclass Xml parsing - Swift</a>

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

Answer1:

A couple of observations:

<ol><li>

Your didStartElement should simply look at attributeDict to get the attributes for an element.

</li> <li>

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.

</li> <li>

The foundCharacters method, if you even needed it, shouldn't have a private didStartElement implemented within it.

</li> <li>

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.

</li> </ol>

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) }

Answer2:

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") } }

Recommend

  • [] operator not supported for strings [duplicate]
  • Can Google GDK Glass Development Kit used with Vuzix glasses?
  • Compiling with OpenMP results in a memory leak
  • using flyway to patch multiple identical schemas
  • How to solve Bad Request (#400) Unable to verify your data submission in yii2?
  • Subsetting DataFrame in R by duplicate values for Year by lowest value for Rating
  • Calculating the occurrences of numbers in the subsets of a data.frame
  • IIS 7.5 404 Error for .PDF files
  • how to load css classes from my own project specfic css in Sitecore's RAD editor?
  • Filter on CALayer except for a shape which is an union of (non necessarily distinct) rectangles
  • Autohotkey script running program with command line arguments
  • Reading a file into a multidimensional array
  • Object and struct member access and address offset calculation
  • WPF ICommand CanExecute(): RaiseCanExecuteChanged() or automatic handling via DispatchTimer?
  • How solve “Qt: Untested Windows version 10.0 detected!”
  • Hardware Accelerated Image Scaling in windows using C++
  • Magento Fatal error: Maximum execution error solution, on WAMP
  • Linq Objects Group By & Sum
  • C# - Is there a limit to the size of an httpWebRequest stream?
  • Optimizing database types to compact database (SQLite)
  • TFS: Get latest causes slow project reloading
  • Javascript Callbacks with Object constructor
  • Running a C# exe file
  • Trying to switch camera back to front but getting exception
  • How can I use Kendo UI with Razor?
  • Javascript + PHP Encryption with pidCrypt
  • Revoking OAuth Access Token Results in 404 Not Found
  • Buffer size for converting unsigned long to string
  • Free memory of cv::Mat loaded using FileStorage API
  • Angular 2 constructor injection vs direct access
  • Getting Messege Twice Using IMvxMessenger
  • embed rChart in Markdown
  • Programmatically clearing map cache
  • How to get NHibernate ISession to cache entity not retrieved by primary key
  • reshape alternating columns in less time and using less memory
  • Reading document lines to the user (python)
  • How can i traverse a binary tree from right to left in java?
  • How can I use `wmic` in a Windows PE script?
  • Unable to use reactive element in my shiny app
  • How can I use threading to 'tick' a timer to be accessed by other threads?