2014-02-15 17 views
40

Die meisten Beispiele zum Aufrufen von NSXMLParser sind in komplexen Projekten mit Apps enthalten. Wie sieht ein einfaches Beispiel aus, das die Rückrufe veranschaulicht?NSXMLParser Einfaches Beispiel

+2

Stack-Überlauf ist, grundsätzlich und absolut eine Frage/Antwort-Website. Sie können Ihre eigenen Fragen beantworten, aber Sie sollten immer noch zur Form der Website folgen. Ihr Beitrag ist hilfreich (danke!), Aber er entspricht NICHT der Absicht von Stack Overflow. Bitte seien Sie nicht so defensiv und refaktorisieren Sie Ihren Beitrag in Übereinstimmung mit den SO-Praktiken. – bkbeachlabs

+1

Notiert wird beim nächsten Mal mehr zu einem Q & A-Stil. Wie bei GitHub weiß ich nicht, wie man es benutzt. – TJA

+0

Können Sie bitte die Lösung in eine Antwort unten kopieren, damit wir sie updaten können und diese von der unbeantworteten Liste entfernen? Vielen Dank. –

Antwort

10

Als Teil der Erforschung des NSXMLParser habe ich den folgenden wirklich einfachen Code erstellt.

main.m

int main(int argc, const char * argv[]) 
{ 

    @autoreleasepool { 
     NSLog(@"Main Started"); 

     NSError *error = nil; 

     // Load the file and check the result 
     NSData *data = [NSData dataWithContentsOfFile:@"/Users/Tim/Documents/MusicXml/Small.xml" 
              options:NSDataReadingUncached 
              error:&error]; 
     if(error) { 
      NSLog(@"Error %@", error); 

      return 1; 
     } 


     // Create a parser and point it at the NSData object containing the file we just loaded 
     NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; 

     // Create an instance of our parser delegate and assign it to the parser 
     MyXmlParserDelegate *parserDelegate = [[MyXmlParserDelegate alloc] init]; 
     [parser setDelegate:parserDelegate]; 

     // Invoke the parser and check the result 
     [parser parse]; 
     error = [parser parserError]; 
     if(error) 
     { 
      NSLog(@"Error %@", error); 

      return 1; 
     } 

     // All done 
     NSLog(@"Main Ended"); 
    } 
    return 0; 
} 

MyXmlParserDelegate.h

#import <Foundation/Foundation.h> 

@interface MyXmlParserDelegate : NSObject <NSXMLParserDelegate> 

@end 

MyXmlParserDelegate.m

#import "MyXmlParserDelegate.h" 

@implementation MyXmlParserDelegate 

- (void) parserDidStartDocument:(NSXMLParser *)parser { 
    NSLog(@"parserDidStartDocument"); 
} 

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { 
    NSLog(@"didStartElement --> %@", elementName); 
} 

-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    NSLog(@"foundCharacters --> %@", string); 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 
    NSLog(@"didEndElement --> %@", elementName); 
} 

- (void) parserDidEndDocument:(NSXMLParser *)parser { 
    NSLog(@"parserDidEndDocument"); 
} 
@end 

Ich habe es in der Hoffnung geschrieben, dass es jemand anderes hilft.

+0

Danke für den Startpunkt. Sehr hilfreich. –

0

Hier ist eine Swift-Version des ursprünglichen Objective-C-Codes unten.

Es wurde gebaut und getestet mit XCode 7.3. Beim Schreiben des Delegierten fand ich es sehr praktisch, die Funktionsprototypen aus der Dokumentation zu kopieren. Es ist erwähnenswert, dass Swift derzeit ein ziemlich schnelles Ziel ist.

main.swift

import Foundation 

// Let's go 
print("Main: Started") 

// Try to load the file. Display the description of the error if one occurs 
var xmlData : NSData 
do { 
    xmlData = try NSData(contentsOfFile: "/Users/amt/Documents/TestXml/Test.xml", 
         options: .DataReadingMappedIfSafe) 
} 
catch let error as NSError { 
    print("Main: \(error.description)") 

    exit(1) 
} 

// Create a parser and point it at the NSData object containing 
// the file we just loaded 
var parser : NSXMLParser! = NSXMLParser(data: xmlData) 

// Create a parser delegate object and assign it to the parser 
// Beware the "weak" reference and don't try to combine the two lines 
// of code into one unless you like EXC_BAD_ACCESS exceptions 
var parserDelegate : MyXmlParserDelegate = MyXmlParserDelegate() 
parser.delegate = parserDelegate 

// This example also illustrates some of the namespace functions defined in 
// the delegate protocol so enable namespace reporting to see them invoked 
parser.shouldReportNamespacePrefixes = true 

// Parse the document 
if !parser.parse() { 
    // If parse() returned false then an error occurred so display is location 
    // and details 
    let error = parser.parserError 
    let line = parser.lineNumber 
    let col = parser.columnNumber 
    print("Parsing failed at \(line):\(col): \(error?.localizedDescription)") 
} 

// All done 
print("Main: Ended") 
exit(0) 

MyXmlParserDelegate.swift

import Foundation 

class MyXmlParserDelegate:NSObject, NSXMLParserDelegate { 

    @objc func parserDidStartDocument(parser: NSXMLParser) { 
     print("parserDidStartDocument") 
    } 

    @objc func parser(parser: NSXMLParser, didStartElement elementName: String, 
       namespaceURI: String?, qualifiedName qName: String?, 
       attributes attributeDict: [String : String]) { 
     print("didStartElement  --> \(elementName)") 
    } 

    @objc func parser(parser: NSXMLParser, foundCharacters string: String) { 
     print("foundCharacters  --> \(string)") 
    } 

    @objc func parser(parser: NSXMLParser, didEndElement elementName: String, 
       namespaceURI: String?, qualifiedName qName: String?) { 
     print("didEndElement   --> \(elementName)") 
    } 

    @objc func parser(parser: NSXMLParser, didStartMappingPrefix prefix: String, 
       toURI namespaceURI: String) { 
     print("didStartMappingPrefix --> Prefix: \(prefix) toURI: \(namespaceURI)") 
    } 

    @objc func parser(parser: NSXMLParser, didEndMappingPrefix prefix: String) { 
     print("didEndMappingPrefix --> Prefix: \(prefix)") 
    } 

    @objc func parserDidEndDocument(parser: NSXMLParser) { 
     print("parserDidEndDocument") 
    } 
} 
0

Swift 4 Beispiel - Parsing Xib-Datei.

import Foundation 

class XMLTransformer: NSObject { 

    private let parser: XMLParser 
    private var stack = [Node]() 
    private var tree: Node? 

    init(data: Data) { 
     parser = XMLParser(data: data) 
     super.init() 
     parser.delegate = self 
    } 
} 

extension XMLTransformer { 

    func transform() throws -> Node? { 
     parser.parse() 
     if let e = parser.parserError { 
     throw e 
     } 
     assert(stack.isEmpty) 
     assert(tree != nil) 
     return tree 
    } 

} 

extension XMLTransformer: XMLParserDelegate { 

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { 
     guard let tag = Tag(rawValue: elementName) else { 
     return 
     } 
     let node = Node(tag: tag, attributes: attributeDict, nodes: []) 
     stack.append(node) 
    } 

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { 
     guard let tag = Tag(rawValue: elementName) else { 
     return 
     } 
     let lastElement = stack.removeLast() 
     assert(lastElement.tag == tag) 
     if let last = stack.last { 
     last.nodes += [lastElement] 
     } else { 
     tree = lastElement 
     } 
    } 
} 

extension XMLTransformer { 

    enum Tag: String { 
     case document 
     case objects 
     case tableViewCell, tableViewCellContentView 
     case subviews 
     case mapView 
     case constraints, constraint 
     case connections, outlet 
    } 
} 

extension XMLTransformer { 

    class Node { 

     let tag: Tag 
     let attributes: [String : String] 
     var nodes: [Node] 

     init(tag: Tag, attributes: [String : String], nodes: [Node] = []) { 
     self.tag = tag 
     self.attributes = attributes 
     self.nodes = nodes 
     } 
    } 
} 

Verbrauch:

let data = try xib(named: "MapTableViewCell") 
let c = XMLTransformer(data: data) 
let tree = try c.transform() // Here you have parsed XML in a Tree representation.