tinyxml使用技巧

实在是好用呀,优点比如:
1,一次装载到内存,其它地方全用引用即可,一个小指针可以是一个元素,也可是一个节(内部很多子元素)。
2,不用管理元素的内存回收,我是没看源码,号称管理的很好。一个父元素删除,它包含的所有子都释放了。
3,api较少并且,一目了然。
遍历时基本就用三个算法:
1)同级的循环(没用遍历以防会误解包括子节点处理)
//pParent当然是父了
for (TiXmlNode *pSTATE = pParent->FirstChild( “STATE” ); pSTATE; pSTATE = pSTATE->NextSibling(“STATE” ))
{}
注意:要用TiXmlNode *结构,不要用TiXmlElement*
2)当同级的到了最后一个,NextSibling()会返回个空。这时你可以用跳了。
pParent->IterateChildren( pSTATE )
3)以上两个掌握了,就可以玩遍历了。不过,要注意,走到叶子节点时,要跳级。但如果你手工跳了,可能遍历会有重复情况。这时可以使用函数的静态变量喽。可以用静态变量记住父结点。可以用静态list来存放处理过的节点,跳过重复情况。示例代码如下:
void handleExportMap(TiXmlNode * pSrc)
{
if (!pSrc ) return;

static TiXmlNode *bodyItem;

if (“FRAME_BODY” == pSrc->ValueTStr())
{
bodyItem = pSrc ;
}
static TiXmlNode *curpItem;
int t = pSrc ->Type();
printf( “type %d \n” , t);

switch (t)
{
case TiXmlNode :: TINYXML_DOCUMENT:
printf( “Document” );
break ;

case TiXmlNode :: TINYXML_ELEMENT:
printf( “Element [%s]” , pSrc ->Value());
//
if (“CONTENT” == pSrc->ValueTStr())
{
curpItem = pSrc ;
}
if (“MAP” == pSrc->ValueTStr())
{
//跳过MAP的处理
pSrc = curpItem->IterateChildren(pSrc ->Parent());

if (!pSrc )
return ;
else
printf( “Element [%s]” , pSrc ->Value());
}
if (“STATE” == pSrc->ValueTStr() && pSrc == pSrc ->Parent()->LastChild())
{
//跳过STATE的处理
//map中的state
pSrc = curpItem->IterateChildren(pSrc ->Parent()->Parent());

if (!pSrc )
return ;
else
printf( “Element [%s]” , pSrc ->Value());
}

if (“ITEM” == pSrc->ValueTStr())
{

printf( “Element [%s]” , pSrc ->Value());

if (!pSrc ->NoChildren())
{
if (!bMoveItems(pSrc ))
return ;
}

} //end if (!pSrc->NoChildren())
if (“MESSAGE” == pSrc->ValueTStr())
{
curpItem = pSrc ;
if (!bMoveItems(pSrc ))
return ;
}
break ;

case TiXmlNode :: TINYXML_COMMENT:
printf( “Comment: [%s]” , pSrc ->Value());
break ;

case TiXmlNode :: TINYXML_UNKNOWN:
printf( “Unknown” );
break ;

case TiXmlNode :: TINYXML_TEXT:
printf( “Text: [%s]\n” , pSrc ->ToText()->Value());
break ;

case TiXmlNode :: TINYXML_DECLARATION:
printf( “Declaration” );
break ;
default :
break ;
}

if (pSrc ->NoChildren())
{
pSrc = pSrc ->NextSibling();

handleExportMap( pSrc );
}
else
{
//过滤,直到合法
while (pSrc = pSrc->FirstChild())
{
handleExportMap( pSrc );

}

}
}
在这个遍历的框架基础上,可以变化和设计出你的需求了,注意,要分化任务,只做遍历,和只做节点的处理,不要混在一起,不然,一个bug两三天呀。上面的bMoveItems就是当定位到了ITEM节点时,我调用其它的业务处理。因为,人只关注ITEM节点,所以它有一些子节点MAP或子子节点STATE,都在上面一一跳过了。

最后,附上“米”,好“下锅”,注意层次。
<?xml version=”1.0″ encoding=”UTF-8″ ?>
<!– edited with XMLSpy v2013 (http://www.altova.com) by () –>
<LINE ID=”11″ VERSION=”1″>
<FRAME_HEADER>
<ITEM ID=”system_id” LENGTH=”1″ CURPOS=”0″ />
<ITEM ID=”total_length” LENGTH=”2″ CURPOS=”1″ MAX_VALUE=”1025″ />
<ITEM ID=”multi_flag” LENGTH=”1″ CURPOS=”3″ DEFAULT=”0″ />
</FRAME_HEADER>
<FRAME_BODY>
<MESSAGE ID=”NETWORK_ALIVE_STATUS” TYPE=”1″ TRANS=”O2N”>
<ITEM ID=”message_length” LENGTH=”2″ CURPOS=”4″ DESC=”消息长度” MIN_VALUE=”13″ interal_index=”1″ />
<ITEM ID=”time” LENGTH=”4″ CURPOS=”6″ DESC=”时间” FORMAT=”HHMMSS” interal_index=”2″>
<MAP NID=”time” MODE=”1″ SAME=”Y” NINDEX=”2″ KEY=”time|6|4″ DESC=”时间” EX_CODE_KEY=”” />
</ITEM>
<ITEM ID=”version” LENGTH=”2″ CURPOS=”10″ DESC=”版本” DEFAULT=”01H” interal_index=”3″ />
<ITEM ID=”msg_id” LENGTH=”2″ CURPOS=”12″ DESC=”报文ID” interal_index=”4″ />
<CONTENT ID=”data0″ DEFAULT_LEN=”3″>
<ITEM ID=”line_id” LENGTH=”2″ CURPOS=”14″ DESC=”线路号” interal_index=”5″>
<MAP NID=”line_id” MODE=”1″ SAME=”Y” NINDEX=”5″ KEY=”line_id|14|2″ EX_CODE_KEY=”” />
</ITEM>
<ITEM ID=”status” LENGTH=”1″ CURPOS=”16″ DESC=”状态字节:1:代表与当前线路号的信息源(server)连接正常;0:代表断开。” interal_index=”6″>
<MAP NID=”xt_pkg” MODE=”1″ SAME=”N” NINDEX=”6″ KEY=”xt_pkg|16|1″ EX_CODE_KEY=””>
<STATE ID=”11_STATUS_CODE_1″ RAWVALUE=”0x00″ HINT=”通信中断” SAME=”Y”>0x80</STATE>
<STATE ID=”11_STATUS_CODE_2″ RAWVALUE=”0x01″ HINT=”通信正常” SAME=”Y”>0x02</STATE>
</MAP>
</ITEM>
</CONTENT>
</MESSAGE>
<MESSAGE ID=”LOAD_DEVICE_STATUS” TYPE=”1″ TRANS=”N2O”>
<ITEM ID=”message_length” LENGTH=”2″ CURPOS=”4″ DESC=”消息长度” MIN_VALUE=”12″ interal_index=”1″ />
<ITEM ID=”time” LENGTH=”4″ CURPOS=”6″ DESC=”时间” FORMAT=”HHMMSS” interal_index=”2″ />
<ITEM ID=”version” LENGTH=”2″ CURPOS=”10″ DESC=”版本” DEFAULT=”01H” interal_index=”3″ />
<ITEM ID=”msg_id” LENGTH=”2″ CURPOS=”12″ DESC=”报文ID” interal_index=”4″ />
<CONTENT ID=”data0″ DEFAULT_LEN=”2″>
<ITEM ID=”line_id” LENGTH=”2″ CURPOS=”14″ DESC=”线路号” interal_index=”5″ />
</CONTENT>
</MESSAGE>
</MESSAGE>
</FRAME_BODY>
</LINE>

保存和另存,一个TiXmlDocument的SaveFile()函数就搞定了。
生成新的XML时,会用一个api就成了。parent->LinkEndChild(TiXmlNode *);根据不用我解释了吧。加同级,用parent()找父指针嘛。

北京工作居住证攻略

朝阳区人才的位置:三元桥,凤凰城附近
海淀区人才的位置:北京市海淀区西四环北路73号中关村人才发展中心
办理:
首先,你要把自己的证件都复印好,不用等待网络上的信息注册后再准备,但完税证明不要提前,因为有效期只有一个月。
但办这事的入口,还是你公司为你注册了帐号,然后,你就可以登陆并看到办理居住证的链接了。
然后,就是材料最后的准备阶段了,去开完税证明和公司行政打交道完成各种手续。
最后,在提交时,想要办小孩上学要注意随迁问题。住址和居住证跨区的小孩上学问题,需要向学校搞清楚。

年检:
这其实是公司人力的动作,每年四月,他们应该用他们的企业帐号登陆系统,做操作。

续证:
工作居住证到期的前后一个月,要在网上先申请,然后,要去所在区人才,柜台办理。又要拿一大堆打印的申请。

变更:
分公司,住址,随迁等种类变更。但重要的是公司变更吧。
本人下家也具有工作居住证的资质,所以,变更准备材料如下:
(只针对海淀人才)
1)居住证原件(这不用说吧)
2)关于为XXX同志办理《北京市工作居住证》聘用单位变更的申请———-网找模板,加盖公司章
3)聘用单位变更申请———–网找模板,是个人申请,所以不用公章
4)营业执照复印副本
5)离职证明原件+复印件———-注意复印件也要盖章,经办人签字(附句话:经本人同意与原件内容一致)
6)新公司的劳动合同原件+复印件———-注意复印件也要盖章,经办人签字 (附句话: 经本人同意与原件内容一致)
不用每页都有章,最好公司有复印件专用的方章,可以在首页和签字页盖章即可。

说什么诚信声明和进入系统打印申请表,这两项并不需要。
当你的申请被受理后,海淀人才就告诉我,两个月左右,登录看一下系统中办理的状态,如果是完成,那么,你有两个方式来取回自己的居住证。一,让公司人事去办事时顺便取到,二,自己打印一个介绍信,模板不好找,但当时,我把柜台的模板照了下来。这样,可以自己起草一个,找公司盖章,注意只好盖章后,拿这个介绍信才能自己取到。
注销:
也是公司人力的动作,当你想在新公司变更或重新办新的,或其它业务时,前公司应该给你注销先。
注销后,两个月内个人如果没有延期注销的动作,那么你的居住证生命线就over了

延期注销:
当你换的新公司试用期较长,或者暂时没公司,或者工作忙时,可以在注销的两个月最后几天,申请延期注销。
那么你就有了6个月的机动时间。当然,你要登陆系统,自己填写申请并提交。如果你的新公司比较确定,要在备注的内容里体现。据说这样
会不仅有6个月,即使长一些,也能救起证的生命线。提交成功就行,不用去柜台了。

以Qtreeview为例介绍Qt的model/view/item框架

因为,Qtreeview是层次容器,所以会复杂。尤其是加子行的时候。
首先,要找到是哪里加子行。有两个思路:位置索引还是item
1)用model的位置索引方式,定位到要加子行的QModelIndex.
2)用item方式,即后台以批量的list加树时,找到item的位置。
3)用model,如果后台的批量item加完就释放,若无从找到,有一个神器就是Model->itemFromIndex(myparent);这是索引和后台item的桥。
后两种方式归纳来看,也算是从item入手了,而且推荐都使用Item方式加子行,不然,可能会陷入到后台model和view中的QModelIndex的不同步,那个问题会让你乱套的。
然后,找到了加子行的点,就是要找方法了。
1)item->appendRow(传入item的list);
2)Model->insertRows(0, 1, myparent); // 添加一行,注意参数是QModelIndex,要理解树模型中子节点的索引机制
虽然,model有自己的appendRow函数,但是,加一行是没问题,分层次加子行时还是不行的。
而且,在分别使用item对象和QModelIndex对象的Data()和setData()时要注意,默认的role参数,一个是0,一个是257.这是绝对的坑儿。
不然,你设置了,总感觉设置的数据为空,不显示。role是一个新维度的概念,使用很方便,只要传入和调出控制好了,是一大神器。
resizecolumncontent也是个不错的技巧,可以在你设置了model后重新调用,根据内容适应宽度。
代码有点乱:但可以上两棵树,并且都有子行。

  //测试绑定线路报文内容到树控件
  QList <QStandardItem *> items;
  QList <QStandardItem *> childItems;
  for (int i = 0; i < 4; ++i)
  {
  QStandardItem *item = new QStandardItem( QString (“item L%0” ).arg(i));
  if (0 == i)
  item->setCheckable( true );
  items.push_back(item);
  }
  lineModel->appendRow(items);
  for (int i = 0; i < 4; ++i)
  {
  for (int i = 0; i < 4; ++i)
  {
  QStandardItem *item = new QStandardItem( QString (“L%0” ).arg(i));
  if (0 == i)
  item->setCheckable( true );
  childItems.push_back(item);
  }
  items.at(i)->appendRow(childItems);
  //lineModel->setItem(i, 0, childItems.at(i));
  }
  items.clear();
  childItems.clear();
  int iRow = -1;
  for (int i = 0; i < 4; ++i)
  {
  for (int i = 0; i < 3; ++i)
  {
  QStandardItem *item = new QStandardItem( QString (“item R%0” ).arg(i));
  if (0 == i)
  item->setCheckable( true );
  items.push_back(item);
  }
  //items.at(i)->appendRow(items);
  //normalModel->setItem(i, items.at(0));
  normalModel->appendRow(items);
  items.clear();
  iRow++;
  }
  //方式一,以setdata方式加子行
  //QModelIndex myparent = normalModel->index(iRow,0);
  // //myparent = normalModel->index(0, 0, myparent);
  // normalModel->insertRows(0, 1, myparent); // 添加一行
  // normalModel->insertColumns(0, 3, myparent); // 添加三列
  // ui.treeView_normal->reset();
  // ui.treeView_normal->setModel(normalModel);
  // ui.treeView_normal->update();
  // emit ui.treeView_normal->dataChanged(normalModel->index(0, 0), normalModel->index(0, 3, myparent));
  ////for (int i = 0; i<3; i++)
  ////{
  // QModelIndex index = normalModel->index(0, 0, myparent);
  // normalModel->setData(index, “kk”);
  // ui.treeView_normal->reset();
  // ui.treeView_normal->setModel(normalModel);
  // ui.treeView_normal->update();
  // emit ui.treeView_normal->dataChanged(normalModel->index(0, 0), index);
  // normalModel->insertColumns(0, 1, myparent); // 添加一列
  // index = normalModel->index(0, 1, myparent);
  // normalModel->setData(index, “ll”);
  // emit ui.treeView_normal->dataChanged(normalModel->index(0, 0), index);
  // ui.treeView_normal->update();
  // ui.treeView_normal->setModel(normalModel);
  // normalModel->insertColumns(0, 1, myparent); // 添加一列
  // index = normalModel->index(0, 2, myparent);
  // normalModel->setData(index, “mm”);
  // ui.treeView_normal->setModel(normalModel);
  // ui.treeView_normal->update();
  // //ui.treeView_normal->paintEvent()
  // emit ui.treeView_normal->dataChanged(normalModel->index(0, 0), index);
  // ui.treeView_normal->reset();
  ////}
  //myparent = lineModel->index(0,0);
  //QModelIndex tmp = lineModel->index(0, 0,myparent);
  // ui.treeView_line->setCurrentIndex(tmp);
  //方式二,以model的setitem方式加行
  QModelIndex myparent = normalModel->index(iRow, 0);
  for (int i = 0; i < 3; ++i)
  {
  QStandardItem *item = new QStandardItem( QString (“R%0” ).arg(i));
  if (0 == i)
  item->setCheckable( true );
  childItems.push_back(item);
  }
  //items.at(i)->appendRow(childItems);
  QStandardItem * tmp = normalModel->itemFromIndex(myparent);
  tmp->appendRow(childItems);
  childItems.clear();
  //normalModel->setItem(iRow, 0, childItems.at(0));
  QStandardItem *item = new QStandardItem( QString (“RE%0” ).arg(0));
  childItems.push_back(item);
  item = new QStandardItem ( QString( “RE%0” ).arg(1));
  childItems.push_back(item);
  item = new QStandardItem ( QString( “RE%0” ).arg(2));
  childItems.push_back(item);
  normalModel->appendRow(childItems);

自由行泰国

自由行者干货吐血奉献:
感觉用倒叙的时间串起来可读性高。

行程章节:
健议,6-10天,选2-3地,6天以内,可以专注1城。很多老外一处一呆就是一个月。租车租房租泰妹已成文化,一盘水果一帮朋友喝到深夜。直到出行前,多看穷游攻略,锦囊啥的。没确定机票前,并不需要订太多景点的票和接机出租啥的,前者用app提前一天解决,点对点的接驳在当地解决吧,可以议价嘛。

首先,倒数半年吧,拿护照买亚航票赶打折是必须的,购时要额外去除保险的点选,因为那是默认选中的坑,不要在意big sort的积分,它是事后才积上去的。对于行李和机上餐可按需选择。注意因为是低价机票,所以不包含这些的。
确定了行程,可以细化你每一天的安排了。是一个城市,还是要飞来飞去?由于本人家人5人10天。所以,舍弃了久仰的清迈。因为,考虑到小孩和老人,不能以旅行团一样的安排,所以,曼谷+芭提雅+泰南的苏梅+涛岛,事实证明大家很满意。

曼谷是购物之都,大皇宫父母只呆了不到半小时,就吵着要逛街。所以,在最后两天在曼谷购物,不然,提着大小包去玩可是很辛苦。
芭提雅离曼谷近,大巴2小时,方便随时,并且沿海热闹。并不细说,我老婆最钟爱此地。但并不上岛,因为后面有好戏。
苏梅+岛,四天的深度感受,才能让大家忘记北方的寒冷和帝都的#¥¥%#。

飞前倒数一个半月,去搞定签证,在网上找可信的旅行社带办,一人花费2百多吧。

倒数一周时,换外币,因为换币要提前预约的,不然,很可能白跑一趟,我是在中国银行柜台办理的,据说汇率低。
不用换太多美金,真用不上。甚至不用换。我在华夏卡里存了6K(号称每天第一次取钱免手续费,但好像至少会有50铢会被当地ATM扣)
具体的安排:
华夏存入6K
换美金1K(本人中间有马来西亚的transit,出关玩了半天,所以,其实应该直接换马币)
换泰铢4K
当然,要带信用卡喽

倒数第四天时,下淘宝单,买电话卡,happy-7day卡。虽然,电话功能只用了不超过五次,但随时上网帮了很多的忙。因为,要收发订单邮件的和各种app的使用。7天过期后本人找到服务点,加了两天的上网约110铢

倒数第三天,网上值机,打印登机牌,打印各种订单确认(住宿酒店确认,地址信息等)和地图资源(一般酒店大堂都提供)。把手机的旅行app整理到一个文件夹,下载最新版本,先登陆上所有出游app帐号,以防到时找不到帐号,影响大事。
本人的app介绍如下:(重要程度,由上至下)
google maps
booking.com
面包自由行
穷游
私人邮箱设置
亚航

途牛
携程
蚂蜂窝自由行

前四位很强大,他们会互相配合,这里要赞一下面包。我在面包上订了一个安通海洋公园和一个人妖秀,都是质量很高,前一天下单,第二天享受,当然,要拿确认邮件去享受了。当然有条件的话,可以打印出来。泰国的IT水平不高,找到愿意让你使用的打印机很难的。酒店的服务人员不会同意,因为上网有风险,并且电脑都为公用。而没有像中国一样的打印复印店的。所以,你只能找office了,幸好有好心的人帮助。我转发邮件给他,他打印出来。面包上的景点也都可以关联google导航定位。这样,离的近或打车前去,大可尽在掌握。
再有就是booking.com了,的确专业,对订单反应速度巨快,可以结合苹果的passbook。

文化章节:
喝白酒的人注意,泰国找不到白酒,并且,早餐很难找,因为,上午开店的很少。在寺庙不要吵,也不用交门票。

详细行程一览表:

地点/时间/逗留 源–目标机场 景点 事后总结(有血的教训)
北京/马来西亚 PEK—KUL 马来西亚–双子塔–central park–机场商圈 事实上到了central market玩了半天,吃了个饭。有一个30分钟的快轨klia2直达central.
马来西亚/曼谷 KUL–DMK 体验美食,然后休息 到达天黑了,入住,准备第二天一早出发芭提雅
曼谷/芭提雅 坐BTS至下面站之一:1)victoryment station|胜利纪念碑(阿怒烧瓦里拆)2)E7|曼谷市东站|Ekkamai|Eastern Bus Terminal,2号口出就是东站。注:租用面包车.汽车北站(Mo chit) 四方水上市场另一个响亮名字是杜拉拉水上市场(最好提前网购票)可以坐香蕉船,照相,购物,看表演。中午后人开始多,我们去早了。 事实上,酒店前台安排了前往芭提雅的家庭型车,5人一共2000铢
巴堤雅 原路返曼谷 东芭乐园,室内民俗表演,大象表演,骑大象,旅游车参观等。到当地后订房两晚,200人民币一晚,有游泳池,比较舒适。 在著名的红灯区街walking street的西北部找了个性价比很高的酒店,记往在海滩的外圈找,那里会便宜。吃海鲜,游泳,逛街(晚上去,你懂的)
芭提雅/曼谷 当地订房一晚,19,200人民币一晚 大巴车,坐到离廊曼机场近的站,在那里现找酒店,因为要赶飞机去苏梅,到曼后晚间逛了跳蚤市场,咋都咋(东西很多,但必须狠讲价,比MBK的价水份还大)
苏梅岛/20-22 DMK–NST车船联:大巴–>–
Donsak码头->—
Lipa Noi Pier(苏梅亚航集合地)–>-面包车->-酒店
查汶海滩(Chaweng Beach)、波普海滩(Borphut Beach)、拉迈海滩(Lamai Beach)和湄南海滩(Maenam Beach)。 海岛的房间紧张,所以用booking.com早下手了。海难上很热闹,水果很便宜。用面包app订了安通海洋公园,做快艇,浮潜,皮划艇,自助,实在是印象深刻,非常推荐。
龟岛(TAO)/23-24 nakhon si thammarat(NST) –bangkok-Don mueang(DMK)车船联:
酒店–>–Seatran pier->–Donsak pier–>–大巴->-机场-16:10->-FD3187–>-17:30-
潜水,南苑岛,mahead bea(海滩),购物街很多 岛上出租车很贵,要由酒店前台来叫。并且,按地图规划好下车地和游览路线。由于有孩子,不能去南苑岛和潜水。有几个购物区路线。逛的同时,看到了离岛的码头Seatran pier 那里有亚航的接待点,车船联票的入口。
龟岛/曼谷/24-26 DMK–KUL 大船–7座小巴–飞机 一天用来赶路,做大船不用很颠婆。有钱的可以从苏梅飞。
曼谷/北京 KUL–PEK 唐人街,泰拳,nana街 找到大皇宫附近的宾馆住下,第二天路线是,大皇宫,考山路,王权免税店,MBK,克里索普人妖秀。注意,去王权要拿两样东东,护照(本人全程随身)还有是打折地图(免费领于酒店前台,上面有打折卡的)。买的东东可以在机场退税。还有就是湄南河边的人妖秀了。风景和文化大餐。人妖秀很艺术,每个位子送一种自选饮品。第二天,飞京略

囧点:
1)买了个超标的箱子,只能托运,而又没买20kg的行李托运,在机场又要登机了,结果高价买了托运–600银子。
2)爸有个小军刀,老婆有些化妆品被安检拦了,幸好,有免费的寄存,等回来北京后,从机场拿走。
3)爸妈先抵泰国机场,对于入境卡拒填,他以为那个是落地签,语言又不通,真是难为他们了。 汇合后出了机场,打不到taxi,因为,机场很规范,有专门的打的通道,要排队,就一定有打表的taxi。
4)上了车,老爸习惯的往副驾驶一座,可是,司机就站在旁边,比划了半天,老爸往前一看,原来有方向盘。
5)注意,泰铢纸币的1K和100的特别相近,本人就大方的给了1K的小费。
6)由于经停马来西亚,本人换了马币,可返程时赶飞机,没有消费掉剩下的钱,结果,回国后发现中国银行不能换马币。结果,留做纪念了。还有若干泰铢硬币。