【第21期】观点:人工智能到底用 GPU?还是用 FPGA?

xml文件的解析

原创 2016年06月01日 18:16:03

分为两种解析方式:

方式一:sax方式解析

优点:逐行读取和解析,所以速度很快。

缺点:只能解析,不能往xml文件中写数据。


我们需要构建自己的xml解析类。这个类实现 抽象类 SaxDelegator,然后实现里面的3个纯虚函数。

——————————————————————————————————

yjh.xml文件内容:

<?xml version="1.0" encoding="UTF-8"?>
<All>
<Inform name="yjh" age="24" add="北京">
     <school>河南大学</school>
  <company>创思科技</company>
</Inform>
<Inform name="yy" age="25" add="上海">
     <school>北京大学</school>
  <company>清新科技园</company>
</Inform>
</All>

__________________________________________________________________

YjhParser.h

#ifndef YjhParser_h__
#define YjhParser_h__
#include "cocos2d.h"
using namespace cocos2d;
class YjhParser:public Ref,public SAXDelegator
{
public:
 //定义一个数组
 CC_SYNTHESIZE(ValueVector, list, List);
 std::string startElementName;//标签
 ValueMap row; //一行
public:
 //获取文件(这是两段式的写法,静态工厂设计模式)
 static YjhParser*  CreateWithXMLFile(std::string fileName);

 bool initWithXMLFile(std::string fileName);
 //实现代理的3个纯虚函数
 virtual void startElement(void *ctx, const char *name, const char **atts);

 virtual void endElement(void *ctx, const char *name);

 virtual void textHandler(void *ctx, const char *s, int len);

 
};

#endif // YjhParser_h__

________________________________________________________________ 

YjhParser.cpp

#include "YjhParser.h"

//获取解析xml文件的对象
YjhParser*  YjhParser::CreateWithXMLFile(std::string fileName)
{
 YjhParser *parse = new YjhParser;
 if (parse&&parse->initWithXMLFile(fileName)){
  
  parse->autorelease();
  return parse;
 }
 CC_SAFE_DELETE(parse);
 return nullptr;
}

//初始化函数

bool  YjhParser::initWithXMLFile(std::string fileName)
{
 SAXParser parser;
 parser.setDelegator(this);
 std::string filePath = FileUtils::getInstance()->fullPathForFilename(fileName);
 
 return parser.parse(filePath);
}


//实现代理的3个纯虚函数

//开始标签触发函数
void  YjhParser::startElement(void *ctx, const char *name, const char **atts){
 //忽略不用的字段
 CC_UNUSED_PARAM(ctx);
 startElementName = name;
 if (startElementName=="Inform")
 {
  row = ValueMap();
  for (int i = 0; atts[i];i+=2)
  {
   std::string key = (char*)atts[i];
   std::string value = (char*)atts[i+1];
   std::pair<std::string, Value> pair(key, Value(value));
   row.insert(pair);
  }
 }
}

//结束字段触发函数

void  YjhParser::endElement(void *ctx, const char *name){
 
 CC_UNUSED_PARAM(ctx);//不使用这个字段
 std::string endElementName = (char*)name;
 if (endElementName=="Inform")
 {
  //把一行的内容插入到数组中。
  list.push_back(Value(row));
 }

}

//文本内容触发函数

void  YjhParser::textHandler(void *ctx, const char *s, int len){
 CC_UNUSED_PARAM(ctx);//不使用这个字段

 //内容
 std::string content = std::string((char*)s, 0, len);
 std::pair<std::string, Value> pair(startElementName, Value(content));
 row.insert(pair);
}

__________________________________________________________________

YjhParserLayer.h

#ifndef YjhParserLayer_h__
#define YjhParserLayer_h__
#include "cocos2d.h"
#include "YjhParser.h" //自己实现的解析类
USING_NS_CC;
class YjhParserLayer:public Layer
{
public:
 static Scene* createScene();
 virtual bool init();
 CREATE_FUNC(YjhParserLayer);
public:
 //回调函数
 void callBack(Ref* pSender);
};

#endif // YjhParserLayer_h__

__________________________________________________________________

YjhParserLayer.cpp

#include "YjhParserLayer.h"
#include "MyUtility.h"

Scene* YjhParserLayer::createScene()
{
 auto scene = Scene::create();
 auto layer = YjhParserLayer::create();
 scene->addChild(layer);
 return scene;
}
bool YjhParserLayer::init()
{
 if (!Layer::init()){
  return false;
 }
 //创建一个按钮
 MenuItemImage *item = MenuItemImage::create("1.png", "2.png", CC_CALLBACK_1(YjhParserLayer::callBack,this));
 item->setPosition(Vec2(200, 200));
 Menu *menu = Menu::create(item, nullptr);
 menu->setAnchorPoint(Vec2::ZERO);
 menu->setPosition(Vec2::ZERO);
 this->addChild(menu);

 return true;
}

void YjhParserLayer::callBack(Ref* pSender)
{
 CCLOG("%s", MyUtility::gbk_2_utf8("Sax方式解析开始").c_str());
 //
  auto parser= YjhParser::CreateWithXMLFile("yjh.xml");
 ValueVector xmlVector= parser->getList();
 //遍历数组
 for (auto item:xmlVector){
  ValueMap row = item.asValueMap();
  //遍历字典
  for (auto dict:row)
  {
   log("%s=%s", dict.first.c_str(), dict.second.asString().c_str());
  }
 }

}

___________________

结果:

——————————————————————————————————————

网上的一些好的写法。


#pragma once
#include <string>
#include "cocos2d.h"
  
class XMLParser : public cocos2d::Ref, public cocos2d::SAXDelegator
{
public:
    staticXMLParser* parseWithFile(constchar*xmlFileName);
  
    staticXMLParser* parseWithString(constchar*content);
  
    XMLParser();
    virtual ~XMLParser();
 
    //从本地xml文件读取
    bool initWithFile(constchar*xmlFileName);
    //从字符中读取,可用于读取网络中的xml数据
    bool initWithString(constchar*content);
     
    //对应xml标签开始,如:<string name="app_name">
    virtualvoidstartElement(void*ctx,const char*name, constchar**atts);
      
    //对应xml标签结束,如:</string>
    virtualvoidendElement(void*ctx,const char*name);
  
    //对应xml标签文本
    virtualvoidtextHandler(void*ctx,const char*s, intlen);
  
    cocos2d::CCString* getString(constchar*key);
  
private:
    cocos2d::CCDictionary *m_pDictionary;
    std::string m_key;
  
    std::string startXMLElement;
    std::string endXMLElement; 
  
};

#include "XMLParser.h"
 
using namespace std;
using namespace cocos2d;
 
//字符ascii码
// 空格
const static int SPACE =32;
// 换行
const static int NEXTLINE =10;
// tab 横向制表符
const static int TAB =9;
 
XMLParser* XMLParser::parseWithFile(constchar*xmlFileName)
{
    XMLParser *pXMLParser =newXMLParser();
    if( pXMLParser->initWithFile(xmlFileName) )
    {
        pXMLParser->autorelease();  
        returnpXMLParser;
    }
    CC_SAFE_DELETE(pXMLParser);
    returnNULL;
}
 
bool XMLParser::initWithFile(constchar*xmlFileName)
{
    m_pDictionary =newCCDictionary();
    SAXParser _parser;
    _parser.setDelegator(this);
    //获取文件全路径
    string fullPath = FileUtils::getInstance()->fullPathForFilename(xmlFileName);
    CCLog("xml parser full path : %s",fullPath.c_str());
 
    return_parser.parse(fullPath);
}
 
XMLParser* XMLParser::parseWithString(constchar*content)
{
    XMLParser *pXMLParser =newXMLParser();
    if( pXMLParser->initWithString(content) )
    {
        pXMLParser->autorelease();  
        returnpXMLParser;
    }
    CC_SAFE_DELETE(pXMLParser);
    returnNULL;
}
 
bool XMLParser::initWithString(constchar*content)
{
    m_pDictionary =newCCDictionary();
    SAXParser _parse;
    _parse.setDelegator(this);
    return_parse.parse(content, strlen(content) );
}
 
//开始一个节点
// 比如<string name="app_name">小黄人大作战</string>
//name    为     :string
//atts[0] 为属性   : name
//atts[1] 为值        : app_name
//atts[2] 以此类推
void XMLParser::startElement(void *ctx, const char*name,const char**atts)
{
    this->startXMLElement = (char*)name;
    CCLog("start=%s", startXMLElement.c_str());//name
 
    if(this->startXMLElement =="string")
    {
        while(atts && *atts)
        {
            CCLog("attrs0=%s", atts[0]);   //atts[0] : name
            CCLog("attrs1=%s", atts[1]);   //atts[1] : app_name
 
            constchar*attsKey = *atts;   
            if(0== strcmp(attsKey,"name"))
            {
                ++ atts;
                constchar*attsValue = *atts;
                m_key = attsValue;         //key
                break;
            }
            ++ atts;
        }
 
    }
 
}
 
void XMLParser::endElement(void *ctx, const char*name)
{
    this->endXMLElement = (char*)name;
    CCLog("end=%s", endXMLElement.c_str());
}
 
void XMLParser::textHandler(void *ctx, const char*s,int len)
{
    string value((char*)s,0, len);
 
    //是否全是非正常字符
    bool noValue =true;
    for(inti =0; i < len; ++i)
    {
        if(s[i] != SPACE && s[i] != NEXTLINE && s[i] != TAB)
        {
            noValue =false;   
            break;
        }
    }
    if(noValue)return;
    String *pString = String::create(value);
    CCLog("key=%s value=%s", m_key.c_str(), pString->getCString());
    this->m_pDictionary->setObject(pString,this->m_key);
}
 
String* XMLParser::getString(constchar*key)
{
    string strKey(key);
    return(String *)this->m_pDictionary->objectForKey(strKey);
}
 
XMLParser::XMLParser()
{
}
 
XMLParser::~XMLParser()
{
    CC_SAFE_DELETE(this->m_pDictionary);
}



第二种解析方式:Dom解析方式

首先认识dom模型:

注意它有4类节点:

1.文档节点;

2.标记节点;

3.属性节点;

4.根节点;

通过文档节点获取根节点,通过根节点获得子节点,通过子节点获取子节点的属性节点。

层层递推的方式。

在这里有些需要注意的东西就是,实现方式的区别,Dom解析是将dom文档转换为字符串,保存到内存中,然后进行解析。

在做这个实验的时候,出错的地方很多。

但是最主要的是不要忘记引入tinyxml2.h文件,添加该库文件的搜索路径,然后就是解析函数的编写问题了。




版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

C++ XML/xml流解析

最近使用TinyXML进行C++ XML解析,感觉使用起来比较简单,很容易上手,本文给出一个使用TinyXML进行XML解析的简单例子,很多复杂的应用都可以基于本例子的方法来完成。以后的文章里会讲解使...

[Linux C]利用libxml2解析xml文件

为了解析xml,可以使用Linux下默认安装的libxml2。 /* a.c 功能:利用libxml2解析xml文件 */ #include #include #include #i...

XML解析三种方法总结

三种解析无论哪一个,第一步都是校验xml文件 将xml文件在浏览器中打开校验正误 然后观察结构第二步根据xml文件创建javabean类 第三部:根据不同方法进行解析虽然每种解析方法所用到的类或者工具...

xml文件读取

#include #include "tinystr.h" #include "tinyxml.h"bool ReadColourXML(std::string path); bool ReadCo...

C/C++读写xml文件

MSXML2::IXMLDOMDocumentPtr pDoc; MSXML2::IXMLDOMElementPtr  xmlRoot ;  // 创建DOMDocument对象  HRE...
  • kyfvc
  • kyfvc
  • 2013-09-16 17:51
  • 21280

c语言解析xml文档

DOM= Document Object Model,文档对象模型,DOM可以以一种独立于平台和语言的方式访问和修改一个文档的内容和结构。换句话说,这是表示和处理一个HTML或XML文档的常用方法。有...

C++解析XML

下载地址 http://sourceforge.net/projects/tinyxml/ 官网有详细的文档以及API介绍 感觉像javaXML解析文件一样好用 读取和设置xml配置文件是最常用...

xml解析(读取xml,保存文件到xml)

在Android中,实现对XML的解析有三种方式,分别为DOM解析器,SAX解析器和PULL解析器。 DOM解析器 DOM是基于树形结构的节点或信息片段的集合,允许开发人员使用DOM API遍历...

PULL和SAX解析xml文件

最近在学习android方面的知识,今天看到了关于使用PULL和SAX两种不同方式解析xml文件,在这里简单总结一下。SAX是一种基于“推”的解析方式,它是自动将事件推入注册的事件处理器进行处理,所以...

Android 中使用Pull解析XML文件

解析XML文件是非常常用的功能,在Android客户端中,经常与服务器通信都需要xml文件的支持,我们这里介绍一个 简单的xml文件的解析,就是使用android中的pull方法进行解析。在java中,有dom解析和sax解析,这个pull解析有些类 似于sax解析,他
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)