jsonToxml 通过LL型方法实现(C#)[源]

本文介绍了一种将JSON数据格式转换为XML格式的方法。通过词法分析和语法分析,使用.NET平台下的C#语言实现了一个简单的JSON到XML的转换器。该解析器能够处理复杂的JSON数据结构,并将其转化为符合XML标准的格式。

json是网络中一种通用的数据传输格式,在某些时候需要将json数据格式转化成xml,这里发布自己的一个实现过程.

分析过程包括词法分析和语法分析 构建xml三个部分,语法分析采用采用LL型自上到下的方式.

词法分析中需要的基本单位 有Token 类:表示一个词 TokenType

定义

ContractedBlock.gif ExpandedBlockStart.gif Code
enum TokenType
    {
        KEYVALUE,
        VALUE,
        VALUELIST,
        OBJECTLIST,
        ID,
        EXPR,
//:
        BIG_LEFT_BRACKET,//{
        BIG_RIGHT_BRACKET,//}
        MID_LEFT_BRACKET,//[
        MID_RIGHT_BRACKET,//]
        COMMA,//,
        STRING//"xxx"
    }

json语法分析过程 值通常的形式为
 var v = {id:100,id:{id:[20,5]}}
var v = 13;
var v=[a,b,c];

定义的范式为,值,对象序列,键值,值序列,它们的对应关系为

    //值 => id |{对象序列}|[值序列] --对应MathValue()方法解析
    //对象序列=>键值|对象序列,键值 --对应MathObjectList()方法解析;
    //键值=>id:值
    //值序列=>值|值序列,值 --对应MathValueList()方法解析;

(说明:源代码书写有误 Math->应该是Match)

就是说MathValue()匹配json的值

ContractedBlock.gif ExpandedBlockStart.gif Code
 1ExpandedBlockStart.gifContractedBlock.gif /**//// <summary>
 2        /// [ooo]{ID|}[/ooo]
 3        /// </summary>
 4        /// <param name="ooo"></param>
 5        /// <returns></returns>

 6        private void MathValue(XmlNode ooo)
 7ExpandedBlockStart.gifContractedBlock.gif        {
 8            temp = GetInToken();
 9            if (temp.Type == TokenType.ID)
10ExpandedSubBlockStart.gifContractedSubBlock.gif            {
11                ooo.InnerText = temp.Segment;
12            }

13            else if (temp.Type == TokenType.BIG_LEFT_BRACKET)
14ExpandedSubBlockStart.gifContractedSubBlock.gif            {
15
16                MathObjectList(ooo);
17                temp = GetInToken();
18                if (temp.Type != TokenType.BIG_RIGHT_BRACKET)
19                    throw new Exception("不匹配");
20                //操作从堆栈中处理
21            }

22            else if (temp.Type == TokenType.MID_LEFT_BRACKET)
23ExpandedSubBlockStart.gifContractedSubBlock.gif            {
24                //返回节点ast
25                MathValueList(ooo, lastheader);
26                temp = GetInToken();
27                if (temp.Type != TokenType.MID_RIGHT_BRACKET)
28                    throw new Exception("不匹配");
29                //从堆栈中构建
30            }

31            else
32                throw new Exception("不匹配");
33        }

 

ContractedBlock.gif ExpandedBlockStart.gif Code
 1private void MathObjectList(XmlNode root)
 2ExpandedBlockStart.gifContractedBlock.gif        {
 3            temp = GetInToken();
 4            if (temp.Type != TokenType.ID)
 5                throw new Exception("不匹配");
 6            string id = temp.Segment;
 7            this.lastheader = id;
 8
 9            temp = GetInToken();
10            if (temp.Type != TokenType.EXPR) 
11                throw new Exception("不匹配");
12            //MathValue();
13            if (PL(1).Type == TokenType.MID_LEFT_BRACKET)
14ExpandedSubBlockStart.gifContractedSubBlock.gif            {
15                this.lastheader = id;
16                //if(root.ParentNode==null)
17                MathValue(root);
18            }

19            else
20ExpandedSubBlockStart.gifContractedSubBlock.gif            {
21
22                XmlElement elem = doc.CreateElement(id);
23                root.AppendChild(elem);
24                MathValue(elem);
25
26            }

27            //这里不能确定是数组还是 数组就是在root ,ID 就是创建 id,用innertext
28ExpandedSubBlockStart.gifContractedSubBlock.gif            /**/////{ 就是创建id 的节点, 用innerxml
29            //MathValue(elem);
30
31
32            if (PL(1).Type == TokenType.COMMA)
33ExpandedSubBlockStart.gifContractedSubBlock.gif            {
34                temp = GetInToken();
35                MathObjectList(root);
36            }

37        }

38private void MathValueList(XmlNode xml,string header)
39ExpandedBlockStart.gifContractedBlock.gif        {
40            if (string.IsNullOrEmpty(header))
41                header = "Value";
42            XmlNode node1 = doc.CreateElement(header);
43            MathValue(node1);
44            xml.AppendChild(node1);
45            if (PL(1).Type == TokenType.COMMA)
46ExpandedSubBlockStart.gifContractedSubBlock.gif            {
47                temp = GetInToken();
48                MathValueList(xml,header);
49            }

50
51        }

代码中在语法分析的同时进行了xml树的创造,调用的参数为xml的父节点

这样就完成了一个简单的分析,调用的方法为:

           Translator translator = new Translator();
            translator.Tranfile(this.richTextBox1.Text);
            this.richTextBox2.Text = translator.doc.OuterXml;

处理网上的一个示例程序

{
  name:"中国",
  province:[
  {
  name:"黑龙江",
  citys:{
  city:["哈尔滨","大庆"]
  }
  },
  {
  name:"广东",
  citys:{
  city:["广州","深圳","珠海"]
  }
  },
  {
  name:"台湾",
  citys:{
  city:["台北","高雄"]
  }
  },
  {
  name:"新 疆",
  citys:{
  city:["乌鲁木齐"]
  }
  }
  ]
  }

输出结果(格式化后):

 

- < xml >
  < name > 中国 </ name >
- < province >
  < name > 黑龙江 </ name >
- < citys >
  < city > 哈尔滨 </ city >
  < city > 大庆 </ city >
  </ citys >
  </ province >
- < province >
  < name > 广东 </ name >
- < citys >
  < city > 广州 </ city >
  < city > 深圳 </ city >
  < city > 珠海 </ city >
  </ citys >
  </ province >
- < province >
  < name > 台湾 </ name >
- < citys >
  < city > 台北 </ city >
  < city > 高雄 </ city >
  </ citys >
  </ province >
- < province >
  < name > 新 疆 </ name >
- < citys >
  < city > 乌鲁木齐 </ city >
  </ citys >
  </ province >
  </ xml >

 

源代码下载

转载于:https://www.cnblogs.com/lxf120/archive/2009/10/20/1586022.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值