zoukankan      html  css  js  c++  java
  • c#: 解析json, 转成xml, 简单方便

    没看到.net framework中有这样的功能, 懒得到处找了, 索性花点时间自己写一个

      1 /*
      2  * Created by SharpDevelop.
      3  * Date: 2013/6/24
      4  * User: sliencer
      5  * Time: 21:54
      6  * 
      7  * To change this template use Tools | Options | Coding | Edit Standard Headers.
      8  */
      9 using System;
     10 using System.Collections.Generic;
     11 using System.Globalization;
     12 using System.Linq;
     13 using System.Text;
     14 using System.Text.RegularExpressions;
     15 using System.Xml;
     16 
     17 namespace JsonDecoder
     18 {
     19     class Program
     20     {
     21         public static void Main(string[] args)
     22         {
     23             int i=0;
     24             foreach (String element in inputs) {
     25                 JS_Value v=JsonDecoder.Decode(element);
     26                 if (v == null)
     27                     throw Error.InvalidJsonStream;
     28                 String s=v.ToString();
     29                 XmlWriterSettings settings =new XmlWriterSettings();
     30                 settings.Indent = true;
     31                 settings.Encoding = Encoding.UTF8;
     32                 XmlWriter wri = XmlWriter.Create("Output" + (i++) + ".xml", settings);
     33                 v.ToXml(wri, true, "JSon");
     34                 wri.Close();
     35             }
     36         }
     37         static String[] inputs=new string[]{
     38         /*自己找几个json测试一下, 我的是从网站随便找来的, 担心版权问题, 就去掉了*/
     39         @"""test1""", @"""test2""", @"""test3"""
     40         };
     41     }
     42     public abstract class JS_Value
     43     {
     44         public abstract void ToXml(XmlWriter p_wri, bool p_bCreateElement, String p_strElementName);
     45     }
     46     public static class XmlHelper
     47     {
     48         public static String ToValidXmlName(String p_name)
     49         {
     50             /*
     51              * http://www.w3.org/TR/REC-xml/#NT-Name
     52                 NameStartChar       ::=       ":" | [A-Z] | "_" | [a-z] | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] | [#x370-#x37D] | [#x37F-#x1FFF] | [#x200C-#x200D] | [#x2070-#x218F] | [#x2C00-#x2FEF] | [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
     53                 NameChar       ::=       NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
     54              */
     55             string patNameStartChar = @":|[A-Z]|_|[a-z]|[xC0-xD6]|[xD8-xF6]|[xF8-u02FF]|[u0370-u037D]|[u037F-u1FFF]|[u200C-u200D]|[u2070-u218F]|[u2C00-u2FEF]|[u3001-uD7FF]|[uF900-uFDCF]|[uFDF0-uFFFD]";
     56             string patNameChar = patNameStartChar +"|" + @"-|.|[0-9]|xB7|[u0300-u036F]|[u203F-u2040]";
     57             String pat=@"^(" + patNameStartChar + ")" + "(" + patNameChar + ")*$";
     58             if (Regex.Match(p_name, pat, RegexOptions.Singleline).Success)
     59                 return p_name;
     60             else
     61             {
     62                 StringBuilder bld=new StringBuilder();
     63                 for (int i=0;i<p_name.Length;i++)
     64                 {
     65                     bool bMatch=false;
     66                     if (i==0)
     67                         bMatch = Regex.Match(p_name[i].ToString(), patNameStartChar,  RegexOptions.Singleline).Success;
     68                     else
     69                         bMatch = Regex.Match(p_name[i].ToString(), patNameChar,  RegexOptions.Singleline).Success;
     70                     if(bMatch)
     71                         bld.Append(p_name[i]);
     72                     else
     73                         bld.AppendFormat("_x{0:x}_", (int)p_name[i]);
     74                 }
     75                 return bld.ToString();
     76             }
     77         }
     78         public static void WriteStartElement_auto(this XmlWriter wri, String p_strName)
     79         {
     80             if (p_strName.Contains(":"))
     81             {
     82                 String prefix=p_strName.Substring(0, p_strName.LastIndexOf(':'));
     83                 string localName=p_strName.Substring(p_strName.LastIndexOf(':')+1);
     84                 if(String.IsNullOrEmpty(localName))
     85                 {
     86                     localName = p_strName.Substring(0, p_strName.Length-1);
     87                     prefix = "";
     88                 }                
     89                 wri.WriteStartElement(localName, prefix);
     90             } else
     91                 wri.WriteStartElement(p_strName);
     92         }
     93     }
     94     public class JS_String : JS_Value
     95     {
     96         public String RawValue{get;set;}
     97         public String Value{get;set;}
     98         public override string ToString()
     99         {
    100             return RawValue;
    101         }
    102         public override void ToXml(XmlWriter p_wri, bool p_bCreateElement, String p_strElementName)
    103         {
    104             String strEleName=XmlHelper.ToValidXmlName(String.IsNullOrEmpty(p_strElementName)? "Value" : p_strElementName);
    105             if (p_bCreateElement)
    106             {
    107                 p_wri.WriteStartElement_auto(strEleName);
    108             }
    109             p_wri.WriteAttributeString("type", "string");
    110             p_wri.WriteString(Value);
    111             if (p_bCreateElement)
    112             {
    113                 p_wri.WriteEndElement();
    114             }
    115         }//ToXml()
    116     }//class
    117     public class JS_Number: JS_Value
    118     {
    119         public String Number{get;set;}
    120         public override string ToString()
    121         {
    122             return Number;
    123         }
    124         
    125         public override void ToXml(XmlWriter p_wri, bool p_bCreateElement, String p_strElementName)
    126         {
    127             String strEleName=XmlHelper.ToValidXmlName(String.IsNullOrEmpty(p_strElementName)? "Value" : p_strElementName);
    128             if (p_bCreateElement)
    129             {
    130                 p_wri.WriteStartElement_auto(strEleName);
    131             }
    132             p_wri.WriteAttributeString("type", "number");
    133             p_wri.WriteString(Number);
    134             if (p_bCreateElement)
    135             {
    136                 p_wri.WriteEndElement();
    137             }
    138         }
    139     }
    140     public class JS_Object: JS_Value
    141     {
    142         private Dictionary<String, JS_Value> m_properties=new Dictionary<String, JS_Value> ();
    143         public Dictionary<String, JS_Value> Properties{
    144             get{
    145                 return m_properties;
    146             }
    147         }
    148         public override string ToString()
    149         {
    150             if(m_properties.Count<=0)
    151                 return "{}";
    152             else
    153                 return "{" + m_properties.Select(x=>""" + x.Key + "":" + x.Value.ToString())
    154                     .Aggregate((x,y)=> x + ",
    " +y ) +"}";
    155         }
    156         
    157         public override void ToXml(XmlWriter p_wri, bool p_bCreateElement, String p_strElementName)
    158         {
    159             String strEleName=XmlHelper.ToValidXmlName(String.IsNullOrEmpty(p_strElementName)? "Value" : p_strElementName);
    160             if (p_bCreateElement)
    161             {
    162                 p_wri.WriteStartElement_auto(strEleName);
    163             }
    164             p_wri.WriteAttributeString("type", "object");
    165             foreach (String properName in m_properties.Keys) {
    166                 m_properties[properName].ToXml(p_wri, true, properName);
    167             }
    168             if (p_bCreateElement)
    169             {
    170                 p_wri.WriteEndElement();
    171             }
    172         }
    173     }//class JS_Obj
    174     public class JS_Array : JS_Value
    175     {
    176         private List<JS_Value> m_elements=new List<JS_Value>();
    177         public List<JS_Value> Elements{
    178             get{
    179                 return m_elements;
    180             }
    181         }
    182         public override string ToString()
    183         {
    184             if(m_elements.Count<=0)
    185                 return "[]";
    186             else
    187                 return "[" + m_elements.Select(x=>x.ToString()).Aggregate((x,y)=> x + ",
    " +y ) +"]";
    188         }
    189 
    190         
    191         public override void ToXml(XmlWriter p_wri, bool p_bCreateElement, String p_strElementName)
    192         {
    193             String strEleName="Value";
    194             if (p_bCreateElement)
    195             {
    196                 p_wri.WriteStartElement_auto(strEleName);
    197             }
    198             p_wri.WriteAttributeString("type", "array");
    199             foreach (JS_Value element in m_elements) {
    200                 element.ToXml(p_wri, true, p_strElementName);
    201             }
    202             if (p_bCreateElement)
    203             {
    204                 p_wri.WriteEndElement();
    205             }
    206         }
    207     }
    208     public enum enumJSConst{
    209         eTrue, eFalse,eNull
    210     }
    211     public class JS_Const : JS_Value
    212     {
    213         public JS_Const(enumJSConst val){ m_value = val;}
    214         private enumJSConst m_value;
    215         public enumJSConst Value{get{return m_value;}}
    216         
    217         public override string ToString()
    218         {
    219             return m_value.ToString().Substring(1).ToLower();
    220         }
    221         public override void ToXml(XmlWriter p_wri, bool p_bCreateElement, String p_strElementName)
    222         {
    223             String strEleName=XmlHelper.ToValidXmlName(String.IsNullOrEmpty(p_strElementName)? "Value" : p_strElementName);
    224             if (p_bCreateElement)
    225             {
    226                 p_wri.WriteStartElement_auto(strEleName);
    227             }
    228             p_wri.WriteAttributeString("type", "const");
    229             p_wri.WriteString(ToString());
    230             if (p_bCreateElement)
    231             {
    232                 p_wri.WriteEndElement();
    233             }
    234         }
    235 
    236         
    237         public static JS_Const True = new JS_Const(enumJSConst.eTrue);
    238         public static JS_Const False = new JS_Const(enumJSConst.eFalse);
    239         public static JS_Const Null = new JS_Const(enumJSConst.eNull);
    240         
    241     }
    242     public class JsonDecoder
    243     {
    244         public static JS_Value Decode(String p_stream)
    245         {
    246             if (String.IsNullOrWhiteSpace(p_stream))
    247                 return null;
    248             else
    249             {
    250                 String s=p_stream.Trim();
    251                 int nPos=0;
    252                 JS_Value v= GetValue(s, ref nPos);
    253                 if (nPos == s.Length)
    254                     return v;
    255                 else
    256                     throw Error.InvalidJsonStream;
    257             }
    258         }
    259         private static char NextChar(String p_stream, ref int p_currentPos)
    260         {
    261             if (p_currentPos>=p_stream.Length)
    262                 throw Error.InvalidJsonStream;
    263             return p_stream[p_currentPos++];
    264         }
    265         private static void SkipSpaces(String p_stream, ref int p_currentPos)
    266         {
    267             while (p_currentPos<p_stream.Length
    268                    && (Char.IsWhiteSpace(p_stream[p_currentPos])
    269                       /* || Char.IsControl(p_stream[p_currentPos])*/
    270                       )
    271                   )
    272             {
    273                 p_currentPos++;
    274             }//while
    275             
    276         }
    277         private static char PeekChar(String p_stream, int p_currentPos)
    278         {
    279             if (p_currentPos>=p_stream.Length)
    280                 throw Error.InvalidJsonStream;
    281             return p_stream[p_currentPos];
    282         }
    283         public static JS_Value GetValue(String p_stream, ref int p_currentPos)
    284         {
    285             JS_Value newValue=GetConst(p_stream, ref p_currentPos);
    286             if (null == newValue)
    287                 newValue = GetString(p_stream, ref p_currentPos);
    288             if (null == newValue)
    289                 newValue = GetNumber(p_stream, ref p_currentPos);
    290             if (null == newValue)
    291                 newValue = GetObject(p_stream, ref p_currentPos);
    292             if (null == newValue)
    293                 newValue = GetArray(p_stream, ref p_currentPos);
    294             
    295             if(null == newValue)
    296                 throw Error.InvalidJsonStream;
    297             return newValue;
    298         }
    299         public static JS_Number GetNumber(String p_stream, ref int p_currentPos)
    300         {
    301               int nLen = p_stream.Length;
    302               if (p_currentPos>=nLen)
    303                   return null;
    304             String strFraction=@".[0-9]+";
    305             String strExposion=@"[eE][+-]?[0-9]+";
    306             String strPattern=@"^(-)?[1-9][0-9]*(" + strFraction +")?(" + strExposion + ")?";
    307 //            if(p_stream.Substring(p_currentPos).StartsWith("500"))
    308 //                Console.WriteLine("Here");
    309             Regex rex=new Regex(strPattern);
    310             Match m= rex.Match(p_stream.Substring(p_currentPos));
    311             if (!m.Success) {
    312                 /*m = Regex.Match(p_stream.Substring(p_currentPos), strPattern);
    313                 m = Regex.Match(p_stream.Substring(p_currentPos), @"^-?[1-9][0-9]*");
    314                 m = Regex.Match(p_stream.Substring(p_currentPos), @"^-?[1-9][0-9]*");
    315                 m = Regex.Match(p_stream.Substring(p_currentPos), @"^(-)?[1-9][0-9]*");
    316                 m = Regex.Match(p_stream.Substring(p_currentPos), @"^(-)?[1-9][0-9]*");
    317                 */
    318                 return null;
    319             }
    320             JS_Number result=new JS_Number();
    321             result.Number = p_stream.Substring(p_currentPos, m.Groups[0].Length);
    322             p_currentPos += m.Groups[0].Length;
    323             return result;
    324         }
    325         public static JS_Const GetConst(String p_stream, ref int p_currentPos)
    326         {
    327               int nLen = p_stream.Length;
    328               if (p_currentPos>=nLen)
    329                   return null;
    330               string temp=p_stream.Substring(p_currentPos);
    331               if (temp.StartsWith("true",    StringComparison.CurrentCultureIgnoreCase))
    332               {
    333                   p_currentPos+=4;
    334                   return JS_Const.True;
    335               }
    336               if (temp.StartsWith("false",    StringComparison.CurrentCultureIgnoreCase))
    337               {
    338                   p_currentPos+=5;
    339                   return JS_Const.False;
    340               }
    341               if (temp.StartsWith("null",    StringComparison.CurrentCultureIgnoreCase))
    342               {
    343                   p_currentPos+=4;
    344                   return JS_Const.Null;
    345               }
    346               return null;
    347         }
    348         public static JS_Array GetArray(String p_stream, ref int p_currentPos)
    349         {
    350               int nLen = p_stream.Length;
    351               if (p_currentPos>=nLen)
    352                   return null;
    353               int nCurrent=p_currentPos;
    354               if (PeekChar(p_stream, nCurrent) != '[')
    355                   return null;
    356               nCurrent++;
    357               JS_Array result=new JS_Array();
    358               SkipSpaces(p_stream, ref nCurrent);
    359               while(nCurrent<=nLen)
    360               {
    361                   int c=PeekChar(p_stream,nCurrent);
    362                   if (c==']')
    363                   {
    364                       nCurrent++;
    365                       break;
    366                   }
    367                   bool noMorePairs=false;
    368                   while(!noMorePairs)
    369                   {
    370                       JS_Value propertyValue=GetValue(p_stream, ref nCurrent);
    371                       result.Elements.Add(propertyValue);
    372                       SkipSpaces(p_stream, ref nCurrent);
    373                       if (PeekChar(p_stream, nCurrent) != ',')
    374                           noMorePairs=true;
    375                       else
    376                       {
    377                           nCurrent++;
    378                           SkipSpaces(p_stream, ref nCurrent);
    379                       }
    380                   }//inner while
    381               }//outter while
    382             p_currentPos=nCurrent;
    383             return result;
    384         }
    385         public static JS_Object GetObject(String p_stream, ref int p_currentPos)
    386         {
    387               int nLen = p_stream.Length;
    388               if (p_currentPos>=nLen)
    389                   return null;
    390               int nCurrent=p_currentPos;
    391               if (PeekChar(p_stream, nCurrent) != '{')
    392                   return null;
    393               nCurrent++;
    394               JS_Object result=new JS_Object();
    395               SkipSpaces(p_stream, ref nCurrent);
    396               while(nCurrent<=nLen)
    397               {
    398                   int c=PeekChar(p_stream,nCurrent);
    399                   if (c=='}')
    400                   {
    401                       nCurrent++;
    402                       break;
    403                   }
    404                   bool noMorePairs=false;
    405                   while(!noMorePairs)
    406                   {
    407                       JS_String propertyName=GetString(p_stream, ref nCurrent);
    408                       SkipSpaces(p_stream, ref nCurrent);
    409                       Char c1 =NextChar(p_stream,ref nCurrent);
    410                       if (c1!=':')
    411                           throw Error.InvalidJsonStream;
    412                       SkipSpaces(p_stream, ref nCurrent);
    413                       JS_Value propertyValue=GetValue(p_stream, ref nCurrent);
    414                       result.Properties.Add(propertyName.Value, propertyValue);
    415                       SkipSpaces(p_stream, ref nCurrent);
    416                       if (PeekChar(p_stream, nCurrent) != ',')
    417                           noMorePairs=true;
    418                       else
    419                       {
    420                           nCurrent++;
    421                           SkipSpaces(p_stream, ref nCurrent);
    422                       }
    423                   }//inner while
    424               }//outter while
    425             p_currentPos=nCurrent;  
    426             return result;
    427         }
    428         public static JS_String GetString(String p_stream, ref int p_currentPos)
    429         {
    430           int nLen = p_stream.Length;
    431           if (p_currentPos>=nLen)
    432               return null;
    433           JS_String result=new JS_String();
    434           int nCurrent=p_currentPos;
    435           if (PeekChar(p_stream, nCurrent) != '"')
    436               return null;
    437           nCurrent++;
    438           StringBuilder bld=new StringBuilder();
    439           while(nCurrent<=nLen)
    440           {
    441               Char c=p_stream[nCurrent++];
    442               if (c=='"')
    443                   break;
    444               if (c != '\')
    445               {
    446                   bld.Append(c);
    447                   continue;
    448               }
    449               c = NextChar(p_stream, ref nCurrent);
    450               if (c=='"')
    451                   bld.Append('"');
    452               else if (c == '\')
    453                   bld.Append('\');
    454               else if (c == '/')
    455                   bld.Append('/');
    456               else if (c == 'b')
    457                   bld.Append('');
    458               else if (c == 't')
    459                   bld.Append('	');
    460               else if (c == 'r')
    461                   bld.Append('
    ');
    462               else if (c == 'n')
    463                   bld.Append('
    ');
    464               else if (c == 'f')
    465                   bld.Append('f');
    466               else if (c == 'u')
    467               {
    468                   char[] code=new Char[4];
    469                   code[0]=NextChar(p_stream, ref nCurrent);
    470                   code[1]=NextChar(p_stream, ref nCurrent);
    471                   code[2]=NextChar(p_stream, ref nCurrent);
    472                   code[3]=NextChar(p_stream, ref nCurrent);
    473                   int nCodePoint=Int32.Parse(code.ToString(), NumberStyles.HexNumber);
    474                   bld.Append((char)nCodePoint);
    475               }
    476           }//while()
    477           result.Value = bld.ToString();
    478           result.RawValue = p_stream.Substring(p_currentPos, nCurrent-p_currentPos);
    479           p_currentPos=nCurrent;
    480           return result;
    481         }
    482         
    483     } //class JsonDecoder
    484     public static class Error{
    485         public static Exception InvalidJsonStream
    486         {
    487             get
    488             {
    489                 return new Exception("Invalid Json Stream");
    490             }
    491         }
    492     }//class Error
    493 }
  • 相关阅读:
    SQLServer字符串与数字拼接
    今天踩了一个低级坑
    DataTable Linq Group Count where写法
    红米note7几个问题处理
    Svn CleanUp failed解决方案
    VisualSVN 新版本终于支持一个解决方案下多workcopy了,并解决了上个版本一个重要BUG
    UML类图
    EXT.net 1.x TreePanel的一个坑
    AntDesign vue学习笔记(九)自定义文件上传
    C# Convert.ChangeType()
  • 原文地址:https://www.cnblogs.com/sliencer/p/3155768.html
Copyright © 2011-2022 走看看