用状态机实现XML解析器(3)

1. 在内存中构建XML文档,并保存.

XMLDocument xml;
    XMLHANDLE hXml = xml.CreateXml("1.0", "gb2312");
    hXml = xml.NewNode(NULL, "root");  // 创建根节点
    xml.SetAttrValue(hXml, "type", "company"); //添加一个根节点属性
    xml.SetAttrValueInt(hXml, "value", 1);

    XMLHANDLE hContent = xml.NewNode(hXml, NULL, et_text); // 为根节点创建一个子节点(内容)
    xml.SetText(hContent, "这是内容");

    hXml = xml.NewNode(hXml, "software"); // 创建子节点
    hXml = xml.NewNode(hXml, "软件部门");
    XMLHANDLE hChild = xml.NewNode(hXml, "person");
    xml.SetAttrValueInt(hChild, "id", 100020001);
    hChild = xml.NewNode(hXml, "person");
    xml.SetAttrValueInt(hChild, "id", 100020002);
    xml.SaveXml("C://my.xml"); // 保存文档

运行结果:

<?xml version="1.0" encoding="gb2312"?>
<root type="company" value="1">
    这是内容
    <software>
        <软件部门>
            <person/>
            <person/>
        </软件部门>
    </software>
    </root>

说明: XMLHANDLE 是我定义的一个用来标识XML节点的"句柄",任何时候,只要传入句柄,接口就可以操作这个节点.

2. 读取XML文档.

XMLDocument xml1;
if(xml1.LoadXml(strFilePath))
{
    XMLHANDLE hRoot = xml1.GetRootNode(); //获取根节点
    string strTypeName = xml1.GetAttrValue(hRoot, "type"); // 获取根节点的属性
    string strContent = xml1.GetContent(xml1.FirstChild(hRoot)); // 获取根节点的第一段内容
    XMLHANDLE hSoftware = xml1.GetChildByName(hRoot, "software");  // 通过节点名定位子节点
    XMLHANDLE hSoftware2 = xml1.GetChildByName(hSoftware, "软件部门");
    XMLHANDLE hPerson = xml1.GetChildByAttr(hSoftware2, "person", "id", "100020002"); //通过属性值定位子节点
    string strId = xml1.GetAttrValue(hPerson, "id");
}


说明:搜索定位接口 GetChildByName() 和 GetChildByAttr() 只搜索指定节点的一级子节点,并不搜索全文.如果要实现全文检索,也不难,用一个栈/队列就可以实现深度优先/广度优先搜索,这是树算法的基本功了.

后记

对于本文介绍的状态分析法 ,画出那张图是关键. 只要能把流程和各个分支想清楚,写代非常容易按部就班就可以写出来.由此也可以看出,用状态分析法来解析XML文档只是这个方法的一次应用.如果你能定义其他的规则,并画出流程,完全可以用这个方法来解析.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wydggf.html