博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
高级排版之HTML,CSS解析
阅读量:5861 次
发布时间:2019-06-19

本文共 2813 字,大约阅读时间需要 9 分钟。

hot3.png

高级排版之HTML,CSS解析

前言

    ****关于HTML的解析是在java层,并且只对文本的内容进行提取,具体的排版是由Typeset出处理,渲染是由TextDraw处理.现今提出的高级排版的需求,这种方式就不满足了,HTML中对于文本的样式的定义,也需要进行解析,即对CSS的解析.并且解析引擎在C++层时间,通过JNI的方式调用.

一、HTML解析

    HTML是可以解析成一个DOM树形,这里定义了其节点的父子关系,并且定义了其层级,以及标签名称,内容的开始和结尾;

class Node{

private:

               long mStart;

              long mLength;

 

              string mStrHTML;

              string mNodeName;

 

              int mLevel;

 

              bool isAttributeParsed;

 

              TAG mTag;

              map<string, string> mAttributes;

              vector<Node *> mSubNodes;

           Node *mPParentNode;

}

    其解析算法就是按照HTML文件流式解析,然后依据当前字符进行不同规则匹配:例如标签的开始字符为’<’,然后遍历字符串,找出标签的名称,属性,以及标签的结束,如果是有子节点,依然重复这个解析算法.这里特别要提到的是如果是以下节点,该节点的内容就要全部作为文本不需要解析.例如:”xmp”,” plaintext”, ”textarea”, ”pre”.

    解析的结果最主要的就是要产生Node的Dom树型数据.这个是由addNode这个方法来保证,示例如下:

Node *HTML::addNode(stack<Node *> &nodeStack, bool isPush2Stack){

    Node *node=new Node();

 

    if(nodeStack.empty()){

       mNodes.push_back(node);//添加到根节点队列中

       node->setLevel(0);

    }else{

       Node *parentNode=nodeStack.top();

       parentNode->addSubNode(*node);//当作上一节点的子节点

       node->setLevel(parentNode->getLevel()+1);

    }

 

    if(isPush2Stack){

       nodeStack.push(node);//当前Node压如栈中

    }

     return node;

}

 

    其HTML文本的内容是有text()方法来获得.text()方法就是要遍历HTML的解析结果vector<Node *>.示例如下:

string HTML::text(){

    string strText;

    if(!mNodes.empty()){

       vector<Node *>::iterator iEnd=mNodes.end();

       for(vector<Node *>::iterator it=mNodes.begin(); it<iEnd; it++){

           extraction(*it, strText);

       }

    }

     return strText;

}

 

void HTML::extraction(Node * n, string &content){

    if(n->getTag()==_tag){

       if(n->hasSubNodes()){

           vector<Node *> nvs=n->getSubNodes();

           vector<Node *>::iterator ivE=nvs.end();

           for(vector<Node *>::iterator i=nvs.begin(); i<ivE; i++){

              extraction(*i, content);

           }

       }else{

           n->append(content);

       }

    }else if(n->getTag()==_text || n->getTag()==_intact_text){

       n->append(content);

    }

}

二、CSS解析

    HTML解析完成之后,就可以通过StyleSheet *HTML::getStyleSheet();方法来获取CSS对象. getStyleSheet()分析HTML中关于<link>部分的内容.最后解析的结果数据结构如下:

       //子串

    struct SubAttr{

       string key;

       string value;

 

       MATCH mat;

    };

   

    //选择器

    struct Selector{

       string elem;

       vector<struct SubAttr *> attrs;

       SLT flag;

 

       string pseudo;

 

       Selector *super;

    };

 

    //声明

    struct Declaration{

       string prop;

       string val;

 

       int weight;

       int count;

    };

 

    //css rule

    struct Rule{

       struct Selector *slt;

       vector<struct Declaration *> decles;

       int weight;

       bool isLayer;

    };

    CSS的解析也还是文本流式解析,从中获取CSS的选择器,申明等,通过addRule方法将生成CSS样式集合.

void StyleSheet::addRule(vector<Rule *> &tempVct, string selName, SLT flag){

    if(!selName.empty()){

 

#ifdef __DEBUG_

       Utils::Log("$$  "+selName+": ");

#endif

 

       struct Rule *pRule;

       pRule=NULL;

 

       vector<Rule *>::iterator itEnd=mRules.end();

       for(vector<Rule *>::iterator it=mRules.begin(); it<itEnd; it++){

           if((*it)->slt->flag==flag && (*it)->slt->elem==selName){

              pRule=*it;

              break;

           }

       }

 

       if(pRule==NULL){

           pRule=new Rule();

           pRule->slt->elem=selName;

           pRule->slt->flag=flag;

 

           mRules.push_back(pRule);//添加到解析结果队列

       }

 

       tempVct.push_back(pRule);//添加到缓存队列

    }

}

转载于:https://my.oschina.net/HandyWorkGroup/blog/159690

你可能感兴趣的文章
状态模式(State Pattern)
查看>>
log4j日志框架学习
查看>>
function 与 => 的区别
查看>>
VBScript:写excel的例子
查看>>
TYVJ P1077 有理逼近 Label:坑,tle的好帮手 不懂
查看>>
面试题:缓存Redis与Memcached的比较 有用
查看>>
通过UIWebView加载读取本地文件
查看>>
由于缺少证书链,导致Android手机提示网站不安全
查看>>
EXCEL自动撤销合并单元格并填充相应内容(转帖)
查看>>
Glide图片框架
查看>>
Python3学习笔记10-条件控制
查看>>
Nginx 1.2.6 稳定版发布
查看>>
黄聪:如何使用CodeSmith批量生成代码(原创系列教程)
查看>>
Deep Learning(深度学习)学习笔记整理系列之(三)
查看>>
close_wait状态的产生原因及解决(转)
查看>>
测试用例设计方法-等价类划分法【转】
查看>>
HDOJ---1421 搬寝室[DP]
查看>>
用 Electron 和 React 撸了个功能超全 + 颜值极高的音乐客户端
查看>>
说说Chrome插件从开发调试到打包发布
查看>>
在Data Lake Analytics中使用视图
查看>>