Синтаксический разбор атрибутов XML

У меня проблема с анализом XML в Swift. Я хотел бы использовать AttributeDict но у меня есть много атрибутов, чтобы использовать его. Так что я использую Dictionary, Но это не работает, и я использую код на этой странице:

Получите attibuteDict синтаксического анализа XML подкласса - Swift

но это все еще не работает. Скажите, знаете ли вы мои XML-данные:

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

И мой не рабочий кодекс:

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

И я не создаю эти данные XML, эти данные XML дают мне мой университет

2 ответа

Решение

Пара наблюдений:

  1. Ваш didStartElement следует просто посмотреть на attributeDict чтобы получить атрибуты для элемента.

  2. Вам не нужен foundCharacters метод в этом случае, потому что вы анализируете только теги элементов, а не анализируете ничего между тегами open и close.

  3. foundCharacters метод, если он вам даже нужен, не должен иметь частного didStartElement реализовано в нем.

  4. Единственный трюк в вашем примере - это то, что у вас очень запутанный XML с вложенными day1 теги. Я бы действительно предложил изменить XML на что-то, что имеет смысл.

    Но, если вы застряли с этим, одно довольно гибкое решение - сохранить стек имен элементов (реализованный в виде простого массива, elementNames), нажмите elementName на стек в didStartElement (добавив в конец массива elementNames) и выскакивает в didEndElement (позвонив по removeLast). Так, например, к тому времени, когда вы нажмете внутренний day1 тег внутри вашего XML, массив elementNames будет ["root", "day1", "day1"],

    Теперь, когда у вас есть это, вы можете проверить, если вы смотрите на day1 внутри другого day1 видя, если последние два пункта в elementNames оба day1,

Например:

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

}

и назовите этот класс

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")
             }
      }
Другие вопросы по тегам