新手学xml

我是个新手,只json,xml和html这些东东,都是传递信息的组织格式。一步一步,我们来充实自己,学一下xml。http的回复就json。

{
 "msgId": 0,
 "resultMsg": "Success",
 "onStatus": {
  "platform": "youtube",
  "status": "living"
 }
}

这就是一个简单的json。今天我们不说json,我们说xml。平时用的少。

一)学习

1. 搞一个创建xml和解析xml的程序,玩一下。不动手你是学不会的。(下面代码原型来源于网络,现在我回馈给网络)

#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>

void print_properties(xmlNodePtr node)
{
    if (!node)
    {
        return;
    }

    xmlAttrPtr attrPtr = node->properties;
    while (attrPtr != NULL)
    {
        xmlChar* attrvalue = xmlGetProp(node, BAD_CAST attrPtr->name);
        printf ("node name:%s  attr name:%s  value:%s\n",
                        node->name, attrPtr->name, attrvalue);
        xmlFree(attrvalue);
        attrPtr = attrPtr->next;
    }
}



int main(int argc, char* argv[])
{
    xmlDocPtr doc = NULL;           //定义解析文件指针
    xmlNodePtr proot = NULL;        //root node
    xmlNodePtr curNode = NULL;      //定义结点指针
    xmlChar *szKey = NULL;          //临时字符串变量
    
    char *szDocName = NULL;
    if (argc <= 1) {
        printf("Usage: %s docname", argv[0]);
        return(0);
    }
    szDocName = argv[1];
   
    
    doc = xmlReadFile(szDocName, "GB2312", XML_PARSE_RECOVER);
    //解析文件
    //检查解析文档是否成功,如果不成功,libxml将报错并停止解析。
    //一个常见错误是不适当的编码,XML标准文档除了用UTF-8或UTF-16外还可用其它编码保存
    if (NULL == doc) {
        fprintf(stderr,"Document not parsed successfully.");
        return -1;
    }

    //获取根节点
    proot = xmlDocGetRootElement(doc);
    if (NULL == proot) {
        fprintf(stderr,"empty document");
        xmlFreeDoc(doc);
        return -1;
    }


    printf ("the root node:%s\n", proot->name);

    curNode = proot->xmlChildrenNode;

    xmlNodePtr childPtr = NULL;

    while(curNode != NULL) 
    {
        //取出节点中的内容
        if ((!xmlStrcmp(curNode->name, (const xmlChar *) "type"))) {
            szKey = xmlNodeGetContent(curNode);
            printf("type: %s\n", szKey);
            xmlFree(szKey);
        }

        if ((!xmlStrcmp(curNode->name, (const xmlChar *) "listen"))) {
            szKey = xmlNodeGetContent(curNode);
            printf("listen: %s\n", szKey);
            xmlFree(szKey);
        }

        if ((!xmlStrcmp(curNode->name, (const xmlChar *) "standard_session_servicedirs"))) {
            szKey = xmlNodeGetContent(curNode);
            printf("standard_session_servicedirs: %s\n", szKey);
            xmlFree(szKey);
        }

        if ((!xmlStrcmp(curNode->name, (const xmlChar *) "policy"))) {
            
            print_properties (curNode);
            
          //  printf("get a policy and save the child node\n");
            childPtr = curNode->xmlChildrenNode;
            while(childPtr != NULL)
            {
                if (!xmlStrcmp(childPtr->name, BAD_CAST "allow")){
                    print_properties (childPtr);
                }
                
                childPtr = childPtr->next;
            }
        }

        curNode = curNode->next;
    }
    xmlFreeDoc(doc);
    return 0;
}

 

#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>

int main()
{    
    xmlChar *result = NULL;
    int size = 0;
    xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");  //定义文档和节点指针
 
    xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST "root");    
    xmlDocSetRootElement(doc,root_node);        //设置根节点
    
    //在根节点中直接创建节点
    xmlNewTextChild(root_node, NULL, BAD_CAST "newNode1", BAD_CAST "newNode1 content");
    xmlNewTextChild(root_node, NULL, BAD_CAST "newNode2", BAD_CAST "newNode2 content");
    xmlNewTextChild(root_node, NULL, BAD_CAST "newNode3", BAD_CAST "newNode3 content");
    
    //创建一个节点,设置其内容和属性,然后加入根结点
    xmlNodePtr node    = xmlNewNode(NULL,BAD_CAST "node2");
    xmlNodePtr content = xmlNewText(BAD_CAST "NODE CONTENT");
    xmlAddChild(root_node,node);
    xmlAddChild(node,content);
    xmlNewProp(node,BAD_CAST "attribute",BAD_CAST "yes");
    
    //创建一个儿子和孙子节点
    node = xmlNewNode(NULL, BAD_CAST "son");
    xmlAddChild(root_node,node);
    xmlNodePtr grandson = xmlNewNode(NULL, BAD_CAST "grandson");
    xmlAddChild(node,grandson);
    //xmlAddChild(grandson, xmlNewText(BAD_CAST "This is a grandson node"));
    xmlNodePtr congson = xmlNewNode(NULL, BAD_CAST "congson");
    xmlAddChild(grandson,congson);
    
    //存储xml文档
    //xmlKeepBlanksDefault(0);
    //xmlDocDumpFormatMemoryEnc(doc, &result, &size, "UTF-8", 1);

    int nRel = xmlSaveFile("CreateXml.xml",doc);
    if (nRel != -1)
    {
        printf("一个xml文档被创建,写入%d个字节\n", nRel);
    }
    //释放文档内节点动态申请的内存
    xmlFreeDoc(doc);
    return 1;
}

注意:在ubuntu中编译时,需要xml2库和xml2的头文件,这些头文件和库又不在标准的地方,你直接编译时编译不过的。

    我编译g++ -o parsexml  parsexml.cpp -I/usr/include/libxml2/ -lxml2,你可以使用命令find  /usr  -name "libxml*"看一下你的系统的xml库在哪里。

    这样你可以创建xml,又能解析了,接下来就是你自己去探索了。

二)知识点

1)xml文件版本,编码说明<?xml version="1.0" encoding="UTF-8"?>这个只能放置版本说明只能放置第一行。

1)xml注释:<!--注释-->

2) 成对的表现有哪几种

    a)  <type>session</type>

    b)  <standard_session_servicedirs/>

3)节点的概念(xml2库)

    每一个<>都是一个节点(element)。<>里面的第一个字符串是节点名称(element name),不能没有节点名称。< />非法  ;<element="1"/>非法。

4)<>里面除了名称,多出来的东西是什么?

    多出来的是属性,properties。属性可以有很多,例如<policy content="default" hen="hen" duo="duo">,属性一定要拿空格隔开;属性必须拿双引号引起来(<test num=1 />非法)。

    在上面的代码中属性的名称被提出到了xmlAttrPtr attrPtr = node->properties;中,但是属性的值还是从节点中拿到的xmlChar* attrvalue = xmlGetProp(node, BAD_CAST attrPtr->name);

<!-- Bus that listens on a debug pipe and doesn't create any restrictions -->
<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
<type>session</type>
<listen>unix:tmpdir=/tmp</listen>
<standard_session_servicedirs />
<policy context="default">
<!-- Allow everything to be sent -->
<allow send_destination="*" eavesdrop="true"/>
<!-- Allow everything to be received -->
<allow eavesdrop="true"/>
<!-- Allow anyone to own anything -->
<allow own="*"/>
<allow user="*"/>
</policy>
</busconfig>

总结:体验xml的层次关系,有节点(element)概念,知道基础知识,那你就入门了。那你就不是新手了。加油啦。

    XML解析方式分为两种:DOM和SAX。你们可以接着探索。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值