XPathQuery के साथ libxml2 एक्सएमएल डोम पार्सिंग

मैं निम्नलिखित xml फ़ाइल को पार्स करने का प्रयास करता हूं:


    Aabach - Hitzkirch
    11.11.2013
    18:00
    2.02
    1.93



    Aach - Salmsach
    11.11.2013
    18:00
    406.47
    406.64

यदि विशेषता "StrNr" "2416" के बराबर है तो मैं तत्व मानों को पढ़ूंगा। मेरा कोड है:

NSURL *url = [NSURL URLWithString:@"http://www.hydrodaten.admin.ch/lhg/SMS.xml"];
NSData *webData = [NSData dataWithContentsOfURL:url options:NSUTF8StringEncoding error:nil];
TFHpple *parser = [TFHpple hppleWithData:webData isXML:YES];
NSString *xPathQuery = @"//AKT_Data/MesPar";
NSArray *arrayPaser= [parser searchWithXPathQuery:xPathQuery];

NSMutableArray *arrayName = [[NSMutableArray alloc] initWithCapacity:0];
NSMutableArray *arrayDatum = [[NSMutableArray alloc] initWithCapacity:0];
NSMutableArray *arrayWertDt24h = [[NSMutableArray alloc] initWithCapacity:0];


for (TFHppleElement *element in arrayPaser) {
    if ([[element firstChild] content]!=nil) {
        NSDictionary *attribute=[element attributes];

        NSString *string= [NSString stringWithFormat:@"%@",[attribute valueForKey:@"StrNr"]];

        if ([string isEqualToString:@"2416"]) {

            arrayName addObject:[element ??????];
            arrayDatum addObject:[element ?????];
            arrayWertDt24h addObject:[element ????];
        }

मुझे नहीं पता कि मुझे तत्व से मूल्य कैसे प्राप्त होते हैं?

0
जोड़ा संपादित
विचारों: 1

1 उत्तर

मेरे पास एक समाधान है जिसमें एनएसएक्सएमएल पार्सर और कुछ एनएसएक्सएमएल पार्सर डिलीगेट विधियों का निर्माण शामिल है।

आइए पहले एनएसओब्जेक्ट को उप-वर्गीकृत करें और एक पार्सर क्लास बनाएं। यहां है। एच:

#import 

@interface XMLParser : NSObject

- (id)initWithData:(NSData *)data;
- (BOOL)parse;

@end

यहां आप देख सकते हैं कि हम इस ऑब्जेक्ट को उस डेटा को फ़ीड करेंगे जिसे आप पार्स करना चाहते हैं और उसके बाद हम इसे पार्स करने के लिए कह सकते हैं। पार्स विधि बस एनएसएक्सएमएल पार्सर पार्स विधि के चारों ओर एक रैपर है जिसे आप एक पल में देखेंगे।

एक वर्ग विस्तार वह जगह है जहां हम उन निजी संपत्तियों को जोड़ देंगे जिन्हें हम पार्सिंग के डेटा को प्रबंधित करने के लिए उपयोग करेंगे। यह निम्नानुसार दिखाई देता है:

@interface XMLParser ()


@property (nonatomic, strong) NSData *data;
@property (nonatomic, strong) NSXMLParser *parser;
@property (nonatomic, strong) NSMutableDictionary *objectDict;
@property (nonatomic, strong) NSMutableString *elementDataString;
@property (nonatomic, strong) NSMutableDictionary *wertTwo;
@property (nonatomic, assign, getter = isParsingWertTwo) BOOL parsingWertTwo;

@end

डेटा और पार्सर गुण स्वयं स्पष्टीकरणपूर्ण हैं। objectDict प्रॉपर्टी वह है जिसे हम इस xml से पार्स करने के लिए देख रहे डेटा को संग्रहीत करने के लिए उपयोग करेंगे। ElementDataString तत्व टैग के बीच पार्सर को वर्णित वर्ण रखेगा। हमारे पास एक wertTwo प्रॉपर्टी है और यह इंगित करने के लिए एक झंडा है जब हम दूसरे वर्ट तत्व को पार्स कर रहे हैं। ऐसा इसलिए है कि हम इस दूसरे वर्ट तत्व से गुणों को पकड़ने के लिए सुनिश्चित कर सकते हैं।

कार्यान्वयन की शुरुआत निम्नानुसार दिखाई देती है:

@implementation XMLParser

- (id)initWithData:(NSData *)data
{
    self = [super init];
    if (self) {
        self.data = data;
        self.parser = [[NSXMLParser alloc] initWithData:data];
        self.parser.delegate = self;
        self.objectDict = [@{} mutableCopy];
        self.wertTwo = [@{} mutableCopy];
    }
    return self;
}

- (BOOL)parse
{
    return [self.parser parse];
}

जैसा कि आप प्रारंभकर्ता से देख सकते हैं, हमने वास्तविक पार्सिंग करने के लिए डेटा और पार्सर के साथ आवश्यक वस्तुओं को स्थापित किया है। जैसा कि मैंने उल्लेख किया है पार्स विधि बस NSXMLParser वर्ग की पार्स विधि को लपेटती है। यह वास्तव में एक बूल देता है और यही कारण है कि मैंने इसे यहां वापस करने का भी चयन किया। हमने पार्सर के प्रतिनिधि के रूप में self सेट किया है, इसलिए हमें आवश्यक डेटा प्राप्त करने के लिए प्रतिनिधि प्रोटोकॉल में कुछ विधियों को लागू करना होगा। प्रतिनिधि विधियां निम्नानुसार दिखाई देती हैं:

#pragma mark - NSXMLParserDelegate

- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName
    attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"MesPar"]) {

       //Get the value from the attribute dict of the MesPar element
        NSString *value = attributeDict[@"StrNr"];

       //Compare whether the value is equal to the desired value
        if ([value isEqualToString:@"2416"]) {

           //if the value is equal, add the attribute dict to the object dict
            [self.objectDict addEntriesFromDictionary:attributeDict];

            return;
        }
    }

   //If the element is Wert AND there is an attribute named dt we know this is the second Wert element
    if ([elementName isEqualToString:@"Wert"] && attributeDict[@"dt"]) {

       //add the attribute element to the wertTwo dict
        [self.wertTwo addEntriesFromDictionary:attributeDict];

       //Set the parsing flag to YES so we know where we are in the delegate methods
        self.parsingWertTwo = YES;

        return;
    }
}

- (void)parser:(NSXMLParser *)parser
 didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName
{
   //if this is the Name element, set the element data in the object dict
    if ([elementName isEqualToString:@"Name"]) {
        [self.objectDict setObject:[self.elementDataString copy] forKey:@"name"];

       //set the data to nil since it will be reset by a delegate method for the next element
        self.elementDataString = nil;

        return;
    }

    if ([elementName isEqualToString:@"Datum"]) {
        [self.objectDict setObject:[self.elementDataString copy] forKey:@"datum"];

       //set the data to nil since it will be reset by a delegate method for the next element
        self.elementDataString = nil;

        return;
    }

    if ([elementName isEqualToString:@"Zeit"]) {
        [self.objectDict setObject:[self.elementDataString copy] forKey:@"zeit"];

       //set the data to nil since it will be reset by a delegate method for the next element
        self.elementDataString = nil;

        return;
    }


    if ([elementName isEqualToString:@"Wert"]) {

       //Checks to see if this is the Wert element AND that we are parsing the second element
        if (self.isParsingWertTwo) {
            [self.wertTwo setObject:[self.elementDataString copy] forKey:@"wertTwoString"];

           //set the wertTwo dict for the key wertTwo in the object dict
           //this allows us to pull out this info for the key wertTwo and includes the attribute of dt along with the elementDataString
            [self.objectDict setObject:[self.wertTwo copy] forKey:@"wertTwo"];

           //set the data to nil since it will be reset by a delegate method for the next element
            self.elementDataString = nil;

            return;
        }
        else{
            [self.objectDict setObject:[self.elementDataString copy] forKey:@"wertOne"];

           //set the data to nil since it will be reset by a delegate method for the next element
            self.elementDataString = nil;

            return;
        }
    }
}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
   //You do not have to implement this but if you'd like here you can access `self.objectDict` which should have a representation of your xml you're looking to parse
}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
   //Append the foundCharacters (in between the element tags) to the data string
    [self.elementDataString appendString:string];
}

कोड वास्तव में क्या हो रहा है पर टिप्पणी की गई है लेकिन संक्षेप में, पार्सर इस उदाहरण में प्रतिनिधि, self को सूचित कर रहा है जब कुछ चीजें हो रही हैं जैसे कि जब यह किसी तत्व में आता है या जब यह वर्ण ढूंढता है । ध्यान में रखना एक बात यह है कि elementDataString संपत्ति को आलसी लोड किया जाना चाहिए और हम ऐसा करते हैं:

// lazy loads the elementDataString if it is nil
// it will be set to nil after each time it is set in a dict
// this is why we copy it when we add it to the dict
- (NSMutableString *)elementDataString
{
    if (!_elementDataString) {
        _elementDataString = [NSMutableString string];
    }
    return _elementDataString;
}

ऐसी कई चीजें हैं जिन्हें मैंने संबोधित नहीं किया है जैसे कि पार्सिंग या अतिरिक्त प्रतिनिधि विधियों में त्रुटियां जिन्हें आप रुचि रखते हैं। यह एक विशेष समाधान है जो तृतीय पक्ष लाइब्रेरी पर निर्भर होने के बजाय कक्षाओं में निर्मित का उपयोग करता है।

1
जोड़ा