解析JSON數(shù)據(jù),解析XML


前言
  • 本文是解析 XML(用XML語言寫的數(shù)據(jù)) 和 JSON格式的數(shù)據(jù)
  • 在此聲明:XML是一種語言,JSON是一種數(shù)據(jù)格式


    30-01.png

一.解析JSON格式的數(shù)據(jù)(即:反序列化)


利用NSJSONSerialization對JSON格式的數(shù)據(jù)進行解析
當數(shù)據(jù)結(jié)構(gòu)為 {key:value,key:value,...}的鍵值對的結(jié)構(gòu)時,可以解析成NSDictionary.
當數(shù)據(jù)結(jié)構(gòu)為 ["a","b","c",...]結(jié)構(gòu)時筷凤,可以解析成NSArray.

NSJSONSerialization類中的兩個方法
  • JSON數(shù)據(jù)轉(zhuǎn)成OC對象(反序列化)--->解析JSON格式的數(shù)據(jù)就用這個方法
  • 反序列化目的(通俗理解):轉(zhuǎn)換成OC格式,對于學習OC語法的人來說,能容易看懂
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
  • OC對象轉(zhuǎn)成JSON數(shù)據(jù)(序列化)
+ (NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;


序列化與反序列化:
  • 序列化:在傳輸之前,將對象轉(zhuǎn)換成有序的字符串或者二進制數(shù)據(jù)流
  • 反序列化:將已經(jīng)接收到的字符串或者二進制數(shù)據(jù)流 轉(zhuǎn)換成對象或者數(shù)組,以便程序訪問

注意:
  • Json本質(zhì)上是具有特殊格式的字符串
  • 解析Json的過程就是反序列化的過程
  • 在線代碼格式化:http://tool.oschina.net/codeformat/json
  • 區(qū)分字典和數(shù)組
  • 字典{:镇草,:馋记,}就是key:vaule的形式酿炸,既有冒號又有逗號
  • 數(shù)組[,,,,]中都是逗號隔開

JSON數(shù)據(jù)轉(zhuǎn)成OC對象的詳情代碼1:
  • 注意:創(chuàng)建task使用的是dataTaskWithRequest方法
30-04.png

JSON數(shù)據(jù)轉(zhuǎn)成OC對象的詳情代碼2:
  • 注意:創(chuàng)建task使用的是dataTaskWithURL方法
30-05.png

OC對象轉(zhuǎn)成JSON數(shù)據(jù)的詳情代碼:
30-03.png

JSON解析綜合練習(用NSJSONSerialization創(chuàng)建JSON解析器)
  • 注意區(qū)分里面的面向字典開發(fā)和面向模型
#import "ViewController.h"
#import "UIImageView+WebCache.h"
#import "ZBTableViewCell.h"
#import "ZBVideo.h"
#import <MediaPlayer/MediaPlayer.h>
#import "MJExtension.h"

#define BaseURL @"http://120.25.226.186:32812"

@interface ViewController ()
/** 數(shù)據(jù)源*/
@property (nonatomic ,strong) NSArray *videos;
@end

@implementation ViewController

#pragma mark --------------------
#pragma mark Life Cycle
- (void)viewDidLoad
{
    [super viewDidLoad];
   //有了這句代碼状原,模型中的ID本質(zhì)對應著的是數(shù)據(jù)庫中的id
    //0.告訴框架新值和舊值的對應關(guān)系
    [ZBVideo mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
        return @{
                 @"ID":@"id",
                 };
        
    }];
    //1.發(fā)送請求
    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/video?type=JSON"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        //2.解析數(shù)據(jù) (NSJSONSerialization是解析數(shù)據(jù)的標志)
        NSDictionary *dictM  = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        NSLog(@"%@",dictM);
        
        //復雜json
        //1)寫plist文件到桌面
        [dictM writeToFile:@"/Users/zhangbin/Desktop/video.plist" atomically:YES];
        //2)json在線格式化 http://tool.oschina.net/codeformat/json
        
        //3.設(shè)置tableView的數(shù)據(jù)源(把服務器返回給我們的dictM進行轉(zhuǎn)換,作為tableView的數(shù)據(jù)源,顯示在模擬器上)
        
        /*
         **************************************面向字典開發(fā)**************************************
        //a.面向字典開發(fā)
        //self.videos = dictM[@"videos"];
         
         **************************************面向模型開發(fā)**************************************
        //b.面向模型開發(fā)
        NSArray *arrayM = dictM[@"videos"];
        //字典數(shù)組---->模型數(shù)據(jù)
        NSMutableArray *arr = [NSMutableArray array];
        for (NSDictionary *dict  in arrayM) {
            [arr addObject:[ZBVideo videWithDict:dict]];
        }
        self.videos = arr;
         
         */
        //************************************面向模型開發(fā)**************************************
        //c.利用MJ的框架,進行面向模型開發(fā)(只需要在模型類中聲明對應的屬性菩收,不需要聲明和實現(xiàn)接口方法,并且之前在外界字典轉(zhuǎn)模型需要很多行代碼拨齐,這里只需一行代碼就搞定)
        //dictM[@"videos"]
        self.videos = [ZBVideo mj_objectArrayWithKeyValuesArray:dictM[@"videos"]];
        
        //4.刷新tableView
        dispatch_async(dispatch_get_main_queue(), ^{
             [self.tableView reloadData];//當前類必須繼承UITableViewController驰贷,并且在故事板中設(shè)置關(guān)聯(lián)的類就是當前的控制器盛嘿。否則這行代碼打不出來,會提示錯誤
        });
       
        
    }] resume];
}

#pragma mark --------------------
#pragma mark UITableViewDataSource
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.videos.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"video";
    //1.創(chuàng)建cell
    ZBTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    
    /*
     **************************************面向字典開發(fā)**************************************
     面向字典開發(fā),設(shè)置數(shù)據(jù)的代碼(取出字典中的key中才能拿到數(shù)據(jù)括袒,例如dictM[@"length"])
     
    //NSDictionary *dictM = self.videos[indexPath.row];
    //2.2 設(shè)置標題
    cell.textLabel.text = dictM[@"name"];
    
    //2.3 設(shè)置子標題
    cell.detailTextLabel.text = [NSString stringWithFormat:@"播放時間:%@ 秒",dictM[@"length"]];
    
    //2.4 設(shè)置圖標
    NSURL *url = [NSURL URLWithString:[BaseURL stringByAppendingPathComponent:dictM[@"image"]]];
    
    [cell.imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"Snip20200808_28"]];

     */
    
    
    //**************************************面向模型開發(fā)**************************************
    //面向模型開發(fā),設(shè)置數(shù)據(jù)的代碼(直接從模型中訪問屬性即可拿到數(shù)據(jù)次兆,例如ideoM.length)
    //2.1 獲得該cell對應的數(shù)據(jù)
    ZBVideo *videoM = self.videos[indexPath.row];
    
    //2.2 設(shè)置標題
    cell.textLabel.text = videoM.name;
    
    //2.3 設(shè)置子標題
    cell.detailTextLabel.text = [NSString stringWithFormat:@"播放時間:%@ 秒",videoM.length];
    
    //2.4 設(shè)置圖標 image是NSString類型的
    NSURL *url = [NSURL URLWithString:[BaseURL stringByAppendingPathComponent:videoM.image]];
    
    //占位圖片,當網(wǎng)上的圖片沒下載當指定的cell的時候锹锰,用占位圖片暫時頂替
    [cell.imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"Snip20200808_28"]];
    
    NSLog(@"%@",videoM.ID);
    
    //3.返回cell
    return cell;
}

#pragma mark --------------------
#pragma mark UITableViewDelegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    /* **************************************面向字典開發(fā)**************************************
     
    //1.拿到該cell對應的數(shù)據(jù)
    NSDictionary *dictM  = self.videos[indexPath.row];
    
    //播放該cell對應的視頻
    NSString *urlStr = [BaseURL stringByAppendingPathComponent:dictM[@"url"]];
    */
    
    
    //**************************************面向模型開發(fā)**************************************
    //1.拿到該cell對應的數(shù)據(jù)
    ZBVideo *videoM  = self.videos[indexPath.row];
    
    //播放該cell對應的視頻
    NSString *urlStr = [BaseURL stringByAppendingPathComponent:videoM.url];
    
    //2.創(chuàng)建視頻播放控制器
    MPMoviePlayerViewController *vc = [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL URLWithString:urlStr]];
    
    //3.彈出控制器
    [self presentViewController:vc animated:YES completion:nil];
                        
}
@end

上述代碼截圖
30-06.png

二.解析XML


解析XML的兩種做法
  • NSXMLParser(適合大文件)
  • GDataXMLDocument(不適合大文件)

解析XML的做法一(用NSXMLParser創(chuàng)建XML解析器)

  • 注意:和JSON解析綜合練習的區(qū)別:
  • 解析數(shù)據(jù)的代碼不一樣
  • 讓控制器成為NSXMLParser的代理,代理名稱為NSXMLParserDelegate
  • 字典轉(zhuǎn)模型在代理方法中執(zhí)行
#import "ViewController.h"
#import "UIImageView+WebCache.h"
#import "ZBTableViewCell.h"
#import "ZBVideo.h"
#import <MediaPlayer/MediaPlayer.h>
#import "MJExtension.h"

#define BaseURL @"http://120.25.226.186:32812"

@interface ViewController ()<NSXMLParserDelegate>
/** 數(shù)據(jù)源*/
@property (nonatomic ,strong) NSMutableArray *videos;
@end

@implementation ViewController

#pragma mark --------------------
#pragma mark lazy loading

-(NSMutableArray *)videos
{
    if (_videos == nil) {
        _videos = [NSMutableArray array];
    }
    return _videos;
}
#pragma mark --------------------
#pragma mark Life Cycle
- (void)viewDidLoad
{
    [super viewDidLoad];
   
    //0.告訴框架新值和舊值的對應關(guān)系
    [ZBVideo mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
        return @{
                 @"ID":@"id",
                 };
        
    }];
    //1.發(fā)送請求
    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        //2.解析數(shù)據(jù)
        //2.1 創(chuàng)建XML解析器
        NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
        
        //2.2 設(shè)置代理
        parser.delegate = self;
        
        //2.3 開始解析,該方法本身是阻塞的
        [parser parse];
        
        //4.刷新tableView
        dispatch_async(dispatch_get_main_queue(), ^{
             [self.tableView reloadData];
        });
       
        
    }] resume];
}

#pragma mark --------------------
#pragma mark UITableViewDataSource
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.videos.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"video";
    //1.創(chuàng)建cell
    ZBTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    //2.設(shè)置數(shù)據(jù)

    //2.1 獲得該cell對應的數(shù)據(jù)
  
    ZBVideo *videoM = self.videos[indexPath.row];
    
    //2.2 設(shè)置標題
    cell.textLabel.text = videoM.name;
    
    //2.3 設(shè)置子標題
    cell.detailTextLabel.text = [NSString stringWithFormat:@"播放時間:%@ 秒",videoM.length];
    
    //2.4 設(shè)置圖標
    NSURL *url = [NSURL URLWithString:[BaseURL stringByAppendingPathComponent:videoM.image]];
    
    [cell.imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"Snip20200808_28"]];
    
    NSLog(@"%@",videoM.ID);
    
    //3.返回cell
    return cell;
}

#pragma mark --------------------
#pragma mark UITableViewDelegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

    //1.拿到該cell對應的數(shù)據(jù)
    ZBVideo *videoM  = self.videos[indexPath.row];
    
    //播放該cell對應的視頻
    NSString *urlStr = [BaseURL stringByAppendingPathComponent:videoM.url];
    
    //2.創(chuàng)建視頻播放控制器
    MPMoviePlayerViewController *vc = [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL URLWithString:urlStr]];
    
    //3.彈出控制器
    [self presentViewController:vc animated:YES completion:nil];
                        
}

#pragma mark --------------------
#pragma mark NSXMLParserDelegate
//1.開始解析XML文檔
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
    NSLog(@"%s",__func__);
}

//2.開始解析某個元素   attributeDict:存放著元素的屬性
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict
{
     NSLog(@"%s--開始解析元素%@---\n%@",__func__,elementName,attributeDict);
    
    if ([elementName isEqualToString:@"videos"]) {
        //過濾根元素
        return;
    }
    ZBVideo *videoM = [[ZBVideo alloc]init];
    [videoM mj_setKeyValues:attributeDict];
    [self.videos addObject:videoM];//先調(diào)用videos的懶加載方法芥炭。再將模型裝進大的數(shù)組中

}

//3.某個元素解析完畢
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
     NSLog(@"%s--結(jié)束%@元素的解析",__func__,elementName);
}

//4.整個XML文檔都已經(jīng)解析完畢
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
    NSLog(@"%s",__func__);
}
@end


利用NSXMLParser解析XML和利用NSJSONSerialization解析JSON數(shù)據(jù)的區(qū)別
30-07.png
30-08.png
30-09.png

解析XML的做法二(用GDataXMLDocument創(chuàng)建XML解析器)
  • 注意:和NSXMLParser的區(qū)別:
    • 解析數(shù)據(jù)的代碼不一樣
    • 不需要設(shè)置代理
#import "ViewController.h"
#import "UIImageView+WebCache.h"
#import "ZBTableViewCell.h"
#import "ZBVideo.h"
#import <MediaPlayer/MediaPlayer.h>
#import "MJExtension.h"
#import "GDataXMLNode.h"

#define BaseURL @"http://120.25.226.186:32812"

@interface ViewController ()<NSXMLParserDelegate>
/** 數(shù)據(jù)源*/
@property (nonatomic ,strong) NSMutableArray *videos;
@end

@implementation ViewController

#pragma mark --------------------
#pragma mark lazy loading

-(NSMutableArray *)videos
{
    if (_videos == nil) {
        _videos = [NSMutableArray array];
    }
    return _videos;
}
#pragma mark --------------------
#pragma mark Life Cycle
- (void)viewDidLoad
{
    [super viewDidLoad];
   
    //有了這句代碼,模型中的ID本質(zhì)對應著的是數(shù)據(jù)庫中的id
    
    //0.告訴框架新值和舊值的對應關(guān)系
    [ZBVideo mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
        return @{
                 @"ID":@"id",
                 };
        
    }];
    //1.發(fā)送請求
    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        //2.解析數(shù)據(jù)
                //2.1 加載整個XML文檔
        GDataXMLDocument *doc = [[GDataXMLDocument alloc]initWithData:data options:kNilOptions error:nil];
        
        //2.2 拿到根元素,得到根元素內(nèi)部所有名稱為video的屬性
       NSArray *eles =  [doc.rootElement elementsForName:@"video"];
        
        //2.3 遍歷所有的子元素,得到元素內(nèi)部的屬性數(shù)據(jù)
        for (GDataXMLElement *ele in eles) {
            ZBVideo *videoM = [[ZBVideo alloc]init];
            
            videoM.name = [ele attributeForName:@"name"].stringValue;
            videoM.image = [ele attributeForName:@"image"].stringValue;
            videoM.ID = [ele attributeForName:@"id"].stringValue;
            videoM.length = [ele attributeForName:@"length"].stringValue;
            videoM.url = [ele attributeForName:@"url"].stringValue;
            [self.videos addObject:videoM];
        }
        
        //4.刷新tableView
        dispatch_async(dispatch_get_main_queue(), ^{
             [self.tableView reloadData];
        });
       
        
    }] resume];
}

#pragma mark --------------------
#pragma mark UITableViewDataSource
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.videos.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"video";
    //1.創(chuàng)建cell
    ZBTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    //2.設(shè)置數(shù)據(jù)

    //2.1 獲得該cell對應的數(shù)據(jù)
  
    ZBVideo *videoM = self.videos[indexPath.row];
    
    //2.2 設(shè)置標題
    cell.textLabel.text = videoM.name;
    
    //2.3 設(shè)置子標題
    cell.detailTextLabel.text = [NSString stringWithFormat:@"播放時間:%@ 秒",videoM.length];
    
    //2.4 設(shè)置圖標
    NSURL *url = [NSURL URLWithString:[BaseURL stringByAppendingPathComponent:videoM.image]];
    
    [cell.imageView sd_setImageWithURL:url placeholderImage:[UIImage imageNamed:@"Snip20200808_28"]];
    
   
    NSLog(@"%@",videoM.ID);
    
    //3.返回cell
    return cell;
}

#pragma mark --------------------
#pragma mark UITableViewDelegate
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    //1.拿到該cell對應的數(shù)據(jù)
    ZBVideo *videoM  = self.videos[indexPath.row];
    
    //播放該cell對應的視頻
    NSString *urlStr = [BaseURL stringByAppendingPathComponent:videoM.url];
    
    //2.創(chuàng)建視頻播放控制器
    MPMoviePlayerViewController *vc = [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL URLWithString:urlStr]];
    
    //3.彈出控制器
    [self presentViewController:vc animated:YES completion:nil];
                        
}

@end


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恃慧,一起剝皮案震驚了整個濱河市园蝠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌痢士,老刑警劉巖彪薛,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡善延,警方通過查閱死者的電腦和手機训唱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挚冤,“玉大人况增,你說我怎么就攤上這事⊙档玻” “怎么了澳骤?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長澜薄。 經(jīng)常有香客問我为肮,道長,這世上最難降的妖魔是什么肤京? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任颊艳,我火速辦了婚禮,結(jié)果婚禮上忘分,老公的妹妹穿的比我還像新娘棋枕。我一直安慰自己,他們只是感情好妒峦,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布重斑。 她就那樣靜靜地躺著,像睡著了一般肯骇。 火紅的嫁衣襯著肌膚如雪窥浪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天笛丙,我揣著相機與錄音漾脂,去河邊找鬼。 笑死胚鸯,一個胖子當著我的面吹牛骨稿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蠢琳,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼啊终,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了傲须?” 一聲冷哼從身側(cè)響起蓝牲,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泰讽,沒想到半個月后例衍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體昔期,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年佛玄,在試婚紗的時候發(fā)現(xiàn)自己被綠了硼一。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡梦抢,死狀恐怖般贼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奥吩,我是刑警寧澤哼蛆,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站霞赫,受9級特大地震影響腮介,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜端衰,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一叠洗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧旅东,春花似錦灭抑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至主守,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間榄融,已是汗流浹背参淫。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留愧杯,地道東北人涎才。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像力九,于是被迫代替她去往敵國和親耍铜。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容