2011-03-23 13 views
8

असल में मेरे पास एक एक्सएमएल प्रतिक्रिया है जो लौटाई गई है और एक स्ट्रिंग है, और मुझे एक्सएमएल के माध्यम से लूप करने और सभी जानकारी को सरणी में स्टोर करने की आवश्यकता है। यहाँ एक्सएमएलआईफोन टीबीएक्सएमएल लूपिंग और पार्सिंग डेटा

<?xml version="1.0" encoding="UTF-8"?> 
<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://schema.2sms.com/2.0/schema/0310_ResponseReportStandard.xsd" Version="1.0"> 
    <Error> 
     <ErrorCode>00</ErrorCode> 
     <ErrorReason>OK</ErrorReason> 
    </Error> 
    <ResponseData> 
     <Identification> 
      <UserID>[email protected]</UserID> 
     </Identification> 
     <Result>2 records were returned</Result> 
     <Detail> 
      <ReportTitle>Message Summary: Today</ReportTitle> 
      <Record> 
       <Destination>447790686158</Destination> 
       <Status>WithNetwork</Status> 
       <GUID><![CDATA[2011-03-22T10:54:22.097Z]]></GUID> 
       <DateSubmitted>2011-03-22T10:54:22.097</DateSubmitted> 
       <DateToSend></DateToSend> 
       <DateSent>2011-03-22T10:54:22.533</DateSent> 
       <DateReceived></DateReceived> 
       <Message><![CDATA[Yet again another test]]></Message> 
       <ID>2011-03-22 10:54:22.250HIHIIOJTFVETW85TS</ID> 
      </Record> 
      <Record> 
       <Destination>447790686158</Destination> 
       <Status>SUCCESS</Status> 
       <GUID><![CDATA[2011-03-22T10:50:40.064Z]]></GUID> 
       <DateSubmitted>2011-03-22T10:50:40.063</DateSubmitted> 
       <DateToSend></DateToSend> 
       <DateSent>2011-03-22T10:50:42.473</DateSent> 
       <DateReceived>2011-03-22T10:50:54.570</DateReceived> 
       <Message><![CDATA[This is a test]]></Message> 
       <ID>2011-03-22 10:50:40.210DRUDVMCEZGETW85TS</ID> 
      </Record> 
      <ReportPage ReportID="775797" ItemsPerPage="25" Page="1" TotalItems="2" /> 
     </Detail> 
    </ResponseData> 
</Response> 

मैं उन 2 <records> और वहाँ सभी डेटा की जरूरत है एक सरणी में संग्रहीत किया जा रहा है। इसलिए ....

एक रिकॉर्ड सरणी -> रिकॉर्ड की सरणी -> प्रत्येक रिकॉर्ड, डेटा की सरणी ....

मैं यहाँ बैठे दिया है TBXML जो करने के लिए बहुत आसान है का उपयोग करते हुए इस बाहर काम करने की कोशिश एक एकल नोड हड़पने .... लेकिन मैं इस :(

+2

देखने के लिए कृपया आप और अधिक उत्तर स्वीकार कर सकते हैं यह एक कक्षा विधि नामित किया है। ऐसा लगता है कि आपके कुछ प्रश्नों के उचित उत्तर हैं जिन्हें अस्वीकार्य छोड़ दिया गया है। – occulus

उत्तर

14

ठीक है, आपका पहला कदम एक वर्ग बनाना होगा जो डेटा को पार्स करेगा। उदाहरण के लिए, इसे RecordParser पर कॉल करें। अब हमें हेडर में कुछ विधियों, साथ ही NSMutableArray जोड़ने की आवश्यकता है।

@interface RecordParser : NSObject { 
    NSMutableArray *records;  
} 
@property(nonatomic,retain)NSMutableArray *records; 

-(void)loadRecords:(NSString *)records; 
-(void)traverseElement:(TBXMLElement *)element; 

@end 

अब आगे बढ़ें और अपने कार्यान्वयन में चार्ज करें। अब हमें उन दो तरीकों को लागू करने की आवश्यकता है जो हम चाहते हैं कि हम उन्हें करें।

- (void)loadRecords:(NSString *)records { 
    NSString *someXML = @"http://www.something.com/somexml.xml"; 
    TBXML *tbxml = [[TBXML tbxmlWithURL:[NSURL URLWithString:someXML]] retain]; 

    records = [NSMutableArray array]; 
    [records retain]; 

    if (tbxml.rootXMLElement) 
     [self traverseElement:tbxml.rootXMLElement]; 
    [tbxml release]; 
} 

मूल रूप से यह विधि XML फ़ाइल को प्रश्न में ले जाएगी और पार्सिंग प्रक्रिया शुरू करेगी। साथ ही, आप अपनी सरणी शुरू कर रहे हैं और इसे बनाए रख रहे हैं। अब हम पनीर आते हैं।

- (void) traverseElement:(TBXMLElement *)element { 
    do { 
     if (element->firstChild) 
      [self traverseElement:element->firstChild]; 

     if ([[TBXML elementName:element] isEqualToString:@"Record"]) { 
      TBXMLElement *destination = [TBXML childElementNamed:@"Destination" parentElement:element]; 
      TBXMLElement *status = [TBXML childElementNamed:@"Status" parentElement:element]; 
      TBXMLElement *guid = [TBXML childElementNamed:@"GUID" parentElement:element]; 
      TBXMLElement *dateSub = [TBXML childElementNamed:@"DateSubmitted" parentElement:element]; 
      TBXMLElement *dateToSend = [TBXML childElementNamed:@"DateToSend" parentElement:element]; 
      TBXMLElement *dateSent = [TBXML childElementNamed:@"DateSent" parentElement:element]; 
      TBXMLElement *dateReceived = [TBXML childElementNamed:@"DateReceived" parentElement:element]; 
      TBXMLElement *message = [TBXML childElementNamed:@"Message" parentElement:element]; 
      TBXMLElement *id = [TBXML childElementNamed:@"ID" parentElement:element]; 

      [records addObject:[NSArray arrayWithObjects: 
            [TBXML textForElement:destination], 
            [TBXML textForElement:status], 
            [TBXML textForElement:guid], 
            [TBXML textForElement:dateSub], 
            [TBXML textForElement:dateToSend], 
            [TBXML textForElement:dateSent], 
            [TBXML textForElement:dateReceived], 
            [TBXML textForElement:message], 
            [TBXML textForElement:id],nil]]; 
     } 
    } while ((element = element->nextSibling)); 
} 

असल में क्या विधि करता अनुप्रस्थ एक्सएमएल फ़ाइल नाम आप देख रहे हैं के साथ एक तत्व की तलाश में है, तो यह बच्चे नोड्स से डेटा पकड़ लेता है। इसके अतिरिक्त, डेटा records सरणी में जोड़ा गया है। तो मूल रूप से, जब यह किया जाता है तो आपके पास उस डेटा को होना चाहिए जो आप अपने records सरणी में चाहते हैं, जिसे आप इच्छित सभी चीजों में हेरफेर कर सकते हैं।

यह पूरी तरह से अनचाहे है। अगर यह आपके कंप्यूटर को उड़ाता है और आपकी बिल्ली को मारता है तो मुझे दोष न दें। मैं सामान्य रूप से इस तरह की एक पूरी विधि लिखने के लिए सभी काम नहीं लेता, लेकिन मुझे TBXML पसंद है। अगर यह काम करता है तो कृपया मुझे बताएं। मैं वास्तव में जानने की सराहना करता हूं।

+0

हाँ! धन्यवाद यह वास्तव में काम करता है कि मैं इसे भी कैसे चाहता हूं! लेकिन मैं एक टेबलव्यू सेल में उपयोग किए जाने वाले सरणी से पेटीकुलर प्रविष्टियों का चयन करने के साथ एक और समस्या पर हूं .... लेकिन बहुत धन्यवाद, यह मेरे 2 दिनों के सिरदर्द को ठीक कर रहा है! – MrPink

+0

@MrPink: आपको केवल 'cellForRowAtIndexPath' में अपनी तालिका में प्रदर्शित होने वाले सरणी के' objectAtIndex' को रखना होगा। –

+0

cell.textLabel.text = [एनएसएसटींग स्ट्रिंगविथफॉर्मैट: @ "% @", [रिकॉर्ड ऑब्जेक्टएट इंडेक्स: indexPath.row]]; यह वही है जो मैं उपयोग कर रहा हूं हालांकि यह सरणी – MrPink

0

उपयोग एप्पल के NSXMLParser ऐसा नहीं कर सकते, यह होना किए ओल्ड-स्कूल और सभी लेकिन यह वास्तव में कुशल है

सेटअप अपने XMLParser तदनुसार (NSXMLParserDelegate का उपयोग करें। प्रोटोकॉल)

एक बार आपका पार्सर हिट parser:didStartElement:namespaceURI:qualifiedName:attributes: प्रतिनिधि कॉल वापस कॉल करें और elementNameRecord (जो आप चाहते हैं उससे) के बराबर है।

एलोक 'init' एक NSMutableDictionary। फिर उपरोक्त की तरह elementNameDestination के बराबर है तो [myDictionary setObject: elementName forKey: @"Destination"] और et cætera।

आशा है कि मदद की :)।

लिटिल ओर ध्यान दें: 3 पार्टियों के बजाय Apple's "तकनीक" का उपयोग कर पसंद करते हैं: यह और अधिक कुशल है और संभावनाओं अंतहीन हैं।

+2

हालांकि, टीबीएक्सएमएल 'NSXMLParser' की तुलना में पार्सिंग पर बहुत तेजी से साबित हुआ है। मैं टीबीएक्सएमएल का उपयोग करता हूं और मुझे यह पसंद है। :) –

+0

यह सच है और इस तरह मैं इसे करना चाहता हूं। sudo आप मेरे xml के माध्यम से पार्स करने के लिए tbxml का उपयोग कैसे करेंगे? – MrPink

-2

NSXMLParser का उपयोग करना बेहतर है, क्योंकि यह ऐप्पल की आधिकारिक रिलीज है।

NSXMLParser का सभी दस्तावेज here है।

इसके अलावा, यहां एक NSXMLParser Tutorial है।

+7

एनएसएक्सएमएल पार्सर टीबीएक्सएमएल की तुलना में 3x धीमी है। तथ्य "ऐप्पल" बनाया गया है जो इसे बेहतर नहीं बनाता है। – Sagiftw

1

मैंने टीबीएक्सएमएल लाइब्रेरी के साथ किसी भी उचित ढंग से बनाए गए एक्सएमएल को पार्स करने के लिए रिकर्सिव फ़ंक्शन लिखा था।

मेरी परियोजना में मेरे पास एक्सएमएल का विश्लेषण करने के लिए एक कक्षा है। + (आईडी) infoOfElement: (TBXMLElement *) तत्व

उपयोग कैसे करें:

TBXML *tbxml = [TBXML tbxmlWithXMLData:yourData]; 
TBXMLElement *rootXMLElement = tbxml.rootXMLElement; 

id parsedData = [self infoOfElement: rootXMLElement]; 

    //return NSString or NSDictionary ot NSArray of parsed data 
    + (id) infoOfElement: (TBXMLElement*) element 
    { 
     if (element->text) 
      return [TBXML textForElement:element]; 
     NSMutableDictionary *info = [NSMutableDictionary new]; 
     TBXMLAttribute *attribute = element->firstAttribute; 
     if (attribute) { 
      do { 
       [info setValue:[TBXML attributeValue:attribute] forKey:[TBXML attributeName:attribute]]; 
       attribute = attribute -> next; 
      } while (attribute); 
     } 
     TBXMLElement *child = element->firstChild; 
     if (child){ 
      TBXMLElement *siblingOfChild = child->nextSibling; 
      //If we have array of children with equal name -> create array of this elements 
      if ([[TBXML elementName:siblingOfChild] isEqualToString:[TBXML elementName:child]]){ 
       NSMutableArray *children = [NSMutableArray new]; 
       do { 
        [children addObject:[self infoOfElement:child]]; 
        child = child -> nextSibling; 
       } while (child); 
       return [NSDictionary dictionaryWithObject:children forKey:[TBXML elementName:element]]; 
      } 
      else{ 
       do { 
        [info setValue:[self infoOfElement:child] forKey:[TBXML elementName:child]]; 
        child = child -> nextSibling; 
       } while (child); 
      } 
     }    
     return info; 
    } 
संबंधित मुद्दे