web-dev-qa-db-ja.com

NSXMLParserの簡単な例

NSXMLParserを呼び出す方法の例のほとんどは、アプリを含む複雑なプロジェクトに含まれています。コールバックがどのように見えるかを示す簡単な例は何ですか?.

44
TJA

NSXMLParserの調査の一環として、次の非常に単純なコードを作成しました。

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

他の人を助けることを期待して投稿しました。

13
TJA

Swift 4の例-Xibファイルの解析。

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

使用法:

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.
0
Vlad

以下はSwift以下の元のObjective-Cコードのバージョンです。

XCode 7.3を使用して構築およびテストされました。デリゲートを作成する際、ドキュメントから関数プロトタイプをコピーすると非常に便利です。 Swiftは現在、かなり急速に動いているターゲットです。

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
TJA
#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate, NSXMLParserDelegate>
@property (nonatomic, strong) NSMutableDictionary *dictXML;
@property (nonatomic,strong) NSMutableArray *arrOfUpdateDictsByVersion;
@property (nonatomic,strong) NSString *strElementBeingParsed;
@property (nonatomic,strong) NSString *strElementFinishedParsing;

@end


#import "AppDelegate.h"

@interface AppDelegate ()
@property (weak) IBOutlet NSWindow *window;
@end

@implementation AppDelegate

@synthesize dictXML;
@synthesize arrOfUpdateDictsByVersion;

@synthesize strElementBeingParsed;
@synthesize strElementFinishedParsing;


- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application

    [self initializeTheArray];
    [self startParsingXML];
}

-(void)initializeTheArray{
    self.dictXML = [[NSMutableDictionary alloc] init];
    self.arrOfUpdateDictsByVersion = [[NSMutableArray alloc] init];
}

-(void)startParsingXML{
//    NSXMLParser *xmlparser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://cdn.example.com/databaseupdate.xml"]];
    NSXMLParser *xmlparser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL fileURLWithPath:@"/Users/vkrmsinha/Desktop/xmlParse.xml"]];
    [xmlparser setDelegate:self];
    [xmlparser parse];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;
{
    // initial tag comes in here
    self.strElementBeingParsed = elementName;
    /*if([elementName isEqualToString:@"Version"]){

    }
    else if ([elementName isEqualToString:@"Update"]){

    }*/
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
{

    if(([string rangeOfCharacterFromSet:[NSCharacterSet newlineCharacterSet]].location != NSNotFound) && ![self.strElementBeingParsed isEqualToString:@"Update"])
        return;

    // middle part from between the start and end tags comes here
    if ([self.strElementBeingParsed isEqualToString:@"Update"]){
        NSMutableDictionary *dictUpdate = [NSMutableDictionary dictionary];
        [self.arrOfUpdateDictsByVersion addObject:dictUpdate];
    }
    else if ([self.strElementBeingParsed isEqualToString:@"UpdateType"]){
        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];
        NSMutableDictionary *dictUpd = [NSMutableDictionary dictionary];
        [dictUpd setValue:string forKey:@"UpdateType"];
        [dictUpdate setValue:dictUpd forKey:@"update"];
    }
    else if([self.strElementBeingParsed isEqualToString:@"Version"]){
        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];
        // WARNING: ASK IF NO TWO VERSION WILL BE SAME IN FUTURE
        [dictUpdate setValue:string forKey:@"version"];
    }
    else if ([self.strElementBeingParsed isEqualToString:@"FileName"]){
        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];
        NSMutableDictionary *dict = [dictUpdate objectForKey:@"update"];
        [dict setValue:string forKey:@"FileName"];
    }
    else if ([self.strElementBeingParsed isEqualToString:@"Hash"]){
        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];
        NSMutableDictionary *dict = [dictUpdate objectForKey:@"update"];
        [dict setValue:string forKey:@"Hash"];
    }
    else if ([self.strElementBeingParsed isEqualToString:@"DownloadURL"]){
        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];
        NSMutableDictionary *dict = [dictUpdate objectForKey:@"update"];
        [dict setValue:string forKey:@"DownloadURL"];
    }
    else if ([self.strElementBeingParsed isEqualToString:@"Size"]){
        NSMutableDictionary *dictUpdate = [self.arrOfUpdateDictsByVersion lastObject];
        NSMutableDictionary *dict = [dictUpdate objectForKey:@"update"];
        [dict setValue:string forKey:@"Size"];
    }

}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
{
    // ending of tag comes in here
    self.strElementFinishedParsing = elementName;
    if([elementName isEqualToString:@"Update"]){
        [self.arrOfUpdateDictsByVersion sortUsingDescriptors:[NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"self.version" ascending:YES], nil]];
        NSLog(@"%@", [self.arrOfUpdateDictsByVersion lastObject]);

    }
    if([elementName isEqualToString:@"UpdateDetails"]){
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        [dict setValue:[[self.arrOfUpdateDictsByVersion lastObject] objectForKey:@"version"] forKey:@"latestVer"];
        [dict setValue:[[self.arrOfUpdateDictsByVersion firstObject] objectForKey:@"version"] forKey:@"oldestVer"];
        [dict setValue:self.arrOfUpdateDictsByVersion forKey:@"arrOfUpdsByVer"];
        NSLog(@"%@", dict);
    }

}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
}


<UpdateDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
   <DatabaseUpdates>
    <Update>
     <UpdateType>CompleteDatabase</UpdateType>
     <Version>1</Version>
     <FileName>1completedatabase.Zip</FileName>
     <Hash>ad94431d2fe4cd60eb3347fadaa45d88</Hash>
     <DownloadURL>
      http://www.example.com/download/new.xml
     </DownloadURL>
     <Size>2367008</Size>
    </Update>
</DatabaseUpdates>
</UpdateDetails>
0
Vikram Sinha