【问题标题】:Parsing Wordpress XML iOS / Objective-C解析 Wordpress XML iOS / Objective-C
【发布时间】:2014-03-03 03:08:36
【问题描述】:

我正在尝试创建一个 iOS 应用程序,它(除了一些其他的东西)需要加载到 Wordpress 页面的内容中

当我使用 Wordpress 的 XML-RPC 功能中的 getPosts 功能时,我得到以下返回:

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
  <params>
    <param>
      <value>
      <array><data>
  <value><struct>
  <member><name>post_id</name><value><string>23</string></value></member>
  <member><name>post_title</name><value><string>&lt;!--:de--&gt;Post1&lt;!--:--&gt;&lt;!--:en--&gt;Post1&lt;!--:--&gt;</string></value></member>
  <member><name>post_date</name><value><dateTime.iso8601>20140211T14:26:39</dateTime.iso8601></value></member>
  <member><name>post_date_gmt</name><value><dateTime.iso8601>20140211T12:26:39</dateTime.iso8601></value></member>
  <member><name>post_modified</name><value><dateTime.iso8601>20140217T22:32:45</dateTime.iso8601></value></member>
  <member><name>post_modified_gmt</name><value><dateTime.iso8601>20140217T20:32:45</dateTime.iso8601></value></member>
  <member><name>post_status</name><value><string>publish</string></value></member>
  <member><name>post_type</name><value><string>post</string></value></member>
  <member><name>post_name</name><value><string>im-notfall</string></value></member>
  <member><name>post_author</name><value><string>1</string></value></member>
  <member><name>post_password</name><value><string></string></value></member>
  <member><name>post_excerpt</name><value><string></string></value></member>
  <member><name>post_content</name><value><string>&lt;!--:de--&gt;&lt;b&gt;Post1&lt;/b&gt;&lt;!--:--&gt;&lt;!--:en--&gt;&lt;b&gt;Post1&lt;/b&gt;&lt;!--:--&gt;</string></value></member>
  <member><name>post_parent</name><value><string>0</string></value></member>
  <member><name>post_mime_type</name><value><string></string></value></member>
  <member><name>link</name><value><string>http://example.com/ExampleProjekt/?p=23</string></value></member>
  <member><name>guid</name><value><string>http://example.com/ExampleProjekt/?p=23</string></value></member>
  <member><name>menu_order</name><value><int>5</int></value></member>
  <member><name>comment_status</name><value><string>closed</string></value></member>
  <member><name>ping_status</name><value><string>open</string></value></member>
  <member><name>sticky</name><value><boolean>0</boolean></value></member>
  <member><name>post_thumbnail</name><value><array><data>
</data></array></value></member>
  <member><name>post_format</name><value><string>standard</string></value></member>
  <member><name>terms</name><value><array><data>
  <value><struct>
  <member><name>term_id</name><value><string>1</string></value></member>
  <member><name>name</name><value><string>Allgemein</string></value></member>
  <member><name>slug</name><value><string>allgemein</string></value></member>
  <member><name>term_group</name><value><string>0</string></value></member>
  <member><name>term_taxonomy_id</name><value><string>1</string></value></member>
  <member><name>taxonomy</name><value><string>category</string></value></member>
  <member><name>description</name><value><string></string></value></member>
  <member><name>parent</name><value><string>0</string></value></member>
  <member><name>count</name><value><int>3</int></value></member>
</struct></value>
</data></array></value></member>
  <member><name>custom_fields</name><value><array><data>
</data></array></value></member>
</struct></value>
  <value><struct>
  <member><name>post_id</name><value><string>9</string></value></member>
  <member><name>post_title</name><value><string>&lt;!--:de--&gt;Post2&lt;!--:--&gt;&lt;!--:en--&gt;Post2&lt;!--:--&gt;</string></value></member>
  <member><name>post_date</name><value><dateTime.iso8601>20140206T13:16:56</dateTime.iso8601></value></member>
  <member><name>post_date_gmt</name><value><dateTime.iso8601>20140206T11:16:56</dateTime.iso8601></value></member>
  <member><name>post_modified</name><value><dateTime.iso8601>20140217T22:33:01</dateTime.iso8601></value></member>
  <member><name>post_modified_gmt</name><value><dateTime.iso8601>20140217T20:33:01</dateTime.iso8601></value></member>
  <member><name>post_status</name><value><string>publish</string></value></member>
  <member><name>post_type</name><value><string>post</string></value></member>
  <member><name>post_name</name><value><string>neuer-erster-beitrag</string></value></member>
  <member><name>post_author</name><value><string>1</string></value></member>
  <member><name>post_password</name><value><string></string></value></member>
  <member><name>post_excerpt</name><value><string></string></value></member>
  <member><name>post_content</name><value><string>&lt;!--:de--&gt;&lt;b&gt;Post2&lt;/b&gt;&lt;!--:--&gt;&lt;!--:en--&gt;&lt;b&gt;Post2&lt;/b&gt;&lt;!--:--&gt;</string></value></member>
  <member><name>post_parent</name><value><string>0</string></value></member>
  <member><name>post_mime_type</name><value><string></string></value></member>
  <member><name>link</name><value><string>http://example.com/ExampleProjekt/?p=9</string></value></member>
  <member><name>guid</name><value><string>http://example.com/ExampleProjekt/?p=9</string></value></member>
  <member><name>menu_order</name><value><int>3</int></value></member>
  <member><name>comment_status</name><value><string>closed</string></value></member>
  <member><name>ping_status</name><value><string>open</string></value></member>
  <member><name>sticky</name><value><boolean>0</boolean></value></member>
  <member><name>post_thumbnail</name><value><array><data>
</data></array></value></member>
  <member><name>post_format</name><value><string>standard</string></value></member>
  <member><name>terms</name><value><array><data>
  <value><struct>
  <member><name>term_id</name><value><string>1</string></value></member>
  <member><name>name</name><value><string>Allgemein</string></value></member>
  <member><name>slug</name><value><string>allgemein</string></value></member>
  <member><name>term_group</name><value><string>0</string></value></member>
  <member><name>term_taxonomy_id</name><value><string>1</string></value></member>
  <member><name>taxonomy</name><value><string>category</string></value></member>
  <member><name>description</name><value><string></string></value></member>
  <member><name>parent</name><value><string>0</string></value></member>
  <member><name>count</name><value><int>3</int></value></member>
</struct></value>
</data></array></value></member>
  <member><name>custom_fields</name><value><array><data>
</data></array></value></member>
</struct></value>
  <value><struct>
  <member><name>post_id</name><value><string>5</string></value></member>
  <member><name>post_title</name><value><string>&lt;!--:de--&gt;Post3&lt;!--:--&gt;&lt;!--:en--&gt;Post3&lt;!--:--&gt;</string></value></member>
  <member><name>post_date</name><value><dateTime.iso8601>20131217T17:32:09</dateTime.iso8601></value></member>
  <member><name>post_date_gmt</name><value><dateTime.iso8601>20131217T15:32:09</dateTime.iso8601></value></member>
  <member><name>post_modified</name><value><dateTime.iso8601>20140217T22:33:18</dateTime.iso8601></value></member>
  <member><name>post_modified_gmt</name><value><dateTime.iso8601>20140217T20:33:18</dateTime.iso8601></value></member>
  <member><name>post_status</name><value><string>publish</string></value></member>
  <member><name>post_type</name><value><string>post</string></value></member>
  <member><name>post_name</name><value><string>test-beitrag-2</string></value></member>
  <member><name>post_author</name><value><string>1</string></value></member>
  <member><name>post_password</name><value><string></string></value></member>
  <member><name>post_excerpt</name><value><string></string></value></member>
  <member><name>post_content</name><value><string>&lt;!--:de--&gt;&lt;b&gt;Post3&lt;/b&gt;&lt;!--:--&gt;&lt;!--:en--&gt;&lt;b&gt;Post3&lt;/b&gt;&lt;!--:--&gt;</string></value></member>
  <member><name>post_parent</name><value><string>0</string></value></member>
  <member><name>post_mime_type</name><value><string></string></value></member>
  <member><name>link</name><value><string>http://example.com/ExampleProjekt/?p=5</string></value></member>
  <member><name>guid</name><value><string>http://example.com/ExampleProjekt/?p=5</string></value></member>
  <member><name>menu_order</name><value><int>4</int></value></member>
  <member><name>comment_status</name><value><string>closed</string></value></member>
  <member><name>ping_status</name><value><string>open</string></value></member>
  <member><name>sticky</name><value><boolean>0</boolean></value></member>
  <member><name>post_thumbnail</name><value><array><data>
</data></array></value></member>
  <member><name>post_format</name><value><string>standard</string></value></member>
  <member><name>terms</name><value><array><data>
  <value><struct>
  <member><name>term_id</name><value><string>1</string></value></member>
  <member><name>name</name><value><string>Allgemein</string></value></member>
  <member><name>slug</name><value><string>allgemein</string></value></member>
  <member><name>term_group</name><value><string>0</string></value></member>
  <member><name>term_taxonomy_id</name><value><string>1</string></value></member>
  <member><name>taxonomy</name><value><string>category</string></value></member>
  <member><name>description</name><value><string></string></value></member>
  <member><name>parent</name><value><string>0</string></value></member>
  <member><name>count</name><value><int>3</int></value></member>
</struct></value>
</data></array></value></member>
  <member><name>custom_fields</name><value><array><data>
</data></array></value></member>
</struct></value>
</data></array>
      </value>
    </param>
  </params>
</methodResponse>

具体来说,我需要以下字段:

  • post_id
  • post_title
  • post_motified
  • post_content
  • menu_order

我已经尝试了一些选项来实现这一点。 一个是使用 Gdata,它已在另一篇文章中推荐,但该示例适用于更简单的 xml,我似乎无法让它为我工作。

    NSArray *tempPosts = [XMLdoc nodesForXPath:@"//methodResponse/params/param/value/array/data/value/struct/member" error:nil];

我也尝试过使用 WPXMLRPC 框架 -> https://github.com/wordpress-mobile/wpxmlrpc

使用此代码:

WPXMLRPCDecoder *decodedWPXML = [[WPXMLRPCDecoder alloc] initWithData:XMLcontent];
if ([decodedWPXML isFault]) {
    NSLog(@"XML-RPC error %ld: %@", (long)[decodedWPXML faultCode], [decodedWPXML faultString]);
} else {
    NSLog(@"XML-RPC response: %@", [decodedWPXML object]);
}

我设法接收到一个对象,我可以通过 NSLog(@"%@", object); 输出它 但我无法进一步处理我以这种方式收到的任何数据。 我(对某些人来说可能很明显)对 Objective-c 很陌生。 我还查看了 iOS 应用程序的官方 wordpress,但我无法使用任何代码。

任何帮助将不胜感激,我不介意使用任何不同的框架/技术等,如果它们有助于我的解决方案。

【问题讨论】:

    标签: ios objective-c wordpress xml-rpc gdata


    【解决方案1】:

    我对@9​​87654321@ 很满意,它是免费的。您可以轻松地将您的请求微调到特定页面和帖子类型,这是有据可查的。您从站点返回的始终是 JSON 格式的字典和数组结构(比 XML 更好;)。检查 JSON 结构的好方法是 JSON viewer

    一些示例代码开始使用。

    - (void)loadNewsForPage:(NSUInteger)page
    {
    
        NSURLSession *session = [NSURLSession sharedSession];
        [[session dataTaskWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.mywordpresssite.com/api/get_posts/?page=%lu", (unsigned long)page]]
                completionHandler:^(NSData *data,
                                    NSURLResponse *response,
                                    NSError *error) {
    
                    // handle response
                    NSError *jsonError = nil;
                    id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
    
                    if (!jsonError) {
                        if ([jsonObject isKindOfClass:[NSDictionary class]]) {
    
                            // fill datastore
                            [self newsIntoDataStore:(NSDictionary *)jsonObject forPage:page];
                        }
                        else {
                            NSLog(@"returned jsonObject is not a dictionary!");
                        }
                    } else {
                        NSLog(@"jsonError, news: %@", jsonError);
                    }
    
                }] resume];
    }
    
    - (void)newsIntoDataStore:(NSDictionary *)news forPage:(NSUInteger)page
    {
        if ([[news objectForKey:@"status"] isEqualToString:@"ok"]) {
    
            self.newsPages = [[news objectForKey:@"pages"] integerValue];
            NSArray *posts = [news objectForKey:@"posts"];
    
            if (posts.count > 0) {
                // store individual posts
    
                for (NSDictionary *post in posts) {
    
                    // determine post slug
                    NSArray *categoriesArray = [post objectForKey:@"categories"];
                    NSString *postSlug = nil;
                    NSString *desiredSlug = @"news";
    
                    if (categoriesArray.count > 0) {
                        for (NSDictionary *category in categoriesArray) {
                            if ([[category objectForKey:@"slug"] isEqualToString:desiredSlug]) {
                                postSlug = desiredSlug;
                            }
                        }
                    }
    
                        NSString *title = [post objectForKey:@"title"];
    
                        NSDate *dateFromAPI = [self.dateFormatterFromAPI dateFromString:[post objectForKey:@"date"]];
                        NSString *date = [self.dateFormatterForCell stringFromDate:dateFromAPI];
    
                        NSString *imageURLStringOrg = [[[post objectForKey:@"thumbnail_images"] objectForKey:@"full"] objectForKey:@"url"];
                        NSString *imageURLStringConverted = [imageURLStringOrg stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
                        NSAttributedString *attributedContentString = [[NSAttributedString alloc] initWithData:[[post objectForKey:@"excerpt"] dataUsingEncoding:NSUTF8StringEncoding] options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: [NSNumber numberWithInt:NSUTF8StringEncoding]} documentAttributes:nil error:nil];
                        NSString *content = [attributedContentString string];
    
                        NSString *url = [post objectForKey:@"url"];
    
                        if (title && date && imageURLStringConverted && content && url) {
    
                            NSDictionary *postDictionary = @{@"title" : title, @"date" : date, @"imageURL" : imageURLStringConverted, @"content" : content, @"url" : url};
    
                            [self.newsArray addObject:postDictionary];
    
                        } else {
                            NSLog(@"some post item empty, skipping this post: %lu", (unsigned long)[posts indexOfObject:post]);
                        }
                    }
    
                }
    
                dispatch_async(dispatch_get_main_queue(), ^{
    
                    if (self.pageLoaded < self.newsPages) {
                        [self loadNewsForPage:self.pageLoaded + 1];
                    } else {
    
                        [self.delegate newsFetchingCompleted];
                    }
                });
    
            } else {
                NSLog(@"no objects in the array");
            }
        } else {
            NSLog(@"returned status NOT OK");
        }
    }
    

    【讨论】:

    • 幸运的是,这样我无法获得 menu_order,它消除了在 wordpress 后端手动排序帖子的能力,似乎 WPXMLRPCDecoder 也返回 json-code,但是它只是保存为对象(实际上是一个 NSobject),有什么方法可以将其转换为 NSDictionary?
    • NSObject 只是 NSDictionary 的超类。返回对象的处理是示例代码的一部分,请参见 // 处理响应。检查返回对象的类型。一旦你成功使用 NSDictionary,你就可以开始解析它了。
    • 它适用于您的代码,如果我对从 WPXMLRPCDecoder 返回的对象使用 if 对象 iskindofclass nsdictionary 它返回 false,即使该对象上的 NSLog 在控制台上输出与 JSON 完全相同的代码
    • 我不知道解码器是如何工作的,但如果你说它能够返回 JSON,它应该返回 JSON。我会将服务配置为按照您所说的返回 JSON 并将输出粘贴到 JSON 查看器。不是 NSLog 的打印,而是 URL 会话/连接的数据输出。如果查看器读取输出,则它会被识别为 JSON,您可以检查结构并对其进行解析。
    【解决方案2】:
    GDataXMLDocument *XMLdoc = [[GDataXMLDocument alloc] initWithData:XMLcontent options:0 error:nil];
    NSArray *XMLofPosts = [XMLdoc  nodesForXPath:@"//methodResponse/params/param/value/array/data/value/struct/member" error:nil];
    

    给我一​​个包含所有帖子成员的数组,我可以通过
    for(GDataXMLElement *postMember in XMLofPosts){ ... }

    进行迭代

    感谢您的帮助。 我已经打开了一篇关于该主题的更详细问题的新帖子,因为我发现这是一个非常不同的问题,因为它在 GDataXML 上比获取 Wordpress XML 更重要 GDataXML nodesForXPath on Node contains items of entire GDataXMLDocument

    【讨论】:

      猜你喜欢
      • 2014-06-28
      • 1970-01-01
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多