在不使用XmlDocument.Loadxml()函数的情况下将XML反序列化为JSON

Scr*_*uff 8 c# xml json sqlclr .net-2.0

我有一个独特的问题.我正在将一个dll注册为SQL Server数据库中的一个程序集,该数据库接收一个SQLXml变量以及两个字符串,并将数据序列化为JSON格式.

作为参考,这里是方法调用:

[SqlProcedure]
public static void Receipt(SqlString initiatorPassword,
                           SqlString initiatorId,
                           SqlXml XMLOut,
                           out SqlString strMessge)
Run Code Online (Sandbox Code Playgroud)

如果这是任何其他类型的应用程序,我会使用Newtonsoft.Json或Jayrock这个应用程序.通常我会按照这里给出的答案做一些类似的事情:

XmlReader r = (XmlReader)XmlOut.CreateReader();
XmlDocument doc = new XmlDocument();
doc.load(r);
Run Code Online (Sandbox Code Playgroud)

但是,由于我使用的是SQLClr,因此有一定的规则.其中之一就是.Load()不能使用任何其他继承的方法. 我认为.Net框架说得最好:

System.InvalidOperationException:无法加载动态生成的序列化程序集.在某些托管环境中,组件加载功能受到限制,请考虑使用预生成的序列化程序.有关更多信息,请参阅内部异常.---> System.IO.FileLoadException:
主机已禁用LoadFrom(),LoadFile(),Load(byte [])和LoadModule().

我无论如何都不能流利使用SqlClr,但是如果我正确地理解了这个博客,这是由于SqlCLR的规则不允许.Load()和继承的方法而没有签名并具有强名称.我的DLL和我正在使用的第三方DLL没有强名称,也不能自己重建和签名.所以,这使我无法在不使用负载的情况下尝试完成此任务(除非有人知道另一种方法可以完成)

我能提出的唯一解决方案是一个非常难看的while循环,它无法正常工作,我得到了一个"Jayrock.Json.JsonException:JSON对象中的JSON成员值必须以其成员名称开头"异常.这是我写的while循环(不是我最好的代码,我知道):

 int lastdepth = -1;
 Boolean objend = true;
 Boolean wt = false;
//Write Member/Object statements for the header omitted
JsonWriter w = new JsonTextWriter()
 while (m.Read())
                {
                    if ((lastdepth == -1) && (m.IsStartElement()))
                    {//Checking for root element
                        lastdepth = 0;
                    }
                    if ((m.IsStartElement()) && (lastdepth != -1))
                    {//Checking for Start element ( <html> )
                        w.WriteMember(m.Name);
                        if (objend)
                        { //Check if element is new Parent Node, if so, write start object
                            w.WriteStartObject();
                            objend = false;
                        }
                    }
                    if (m.NodeType == XmlNodeType.Text)
                    { //Writes text here.  NOTE: m.Depth > lastdepth here!!!!!!!
                        w.WriteString(m.Value);
                        wt = true;
                    }
                    if (m.NodeType == XmlNodeType.Whitespace) //If whitespace, keep on truckin
                    { m.Skip(); }
                    if ((m.NodeType == XmlNodeType.EndElement) && (wt == false) && (lastdepth > m.Depth))
                    {//End element that ends a series of "Child" nodes
                        w.WriteEndObject();
                        objend = true;
                    }
                    if ((m.NodeType == XmlNodeType.EndElement) && (wt == true))//Standard end of an el
                    { wt = false; }
                    lastdepth = m.Depth;
                }
                w.WriteEndObject();
                jout = w.ToString();
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,因为我无法使用.load()而我的while循环是一个混乱的调试,这里最好的方法是什么?通常讨论的另一种方法是使用匹配变量反序列化为Object,但我有一个相当大的XML来自SQL Server.我的循环是动态编程的尝试,因为有大约200个字段被用来制作这个XML.

注意:我正在使用Jayrock并在.Net Framework 2.0中工作.我目前无法更改框架版本.

Tra*_*s J 0

JayRock 的代码

您的代码抛出异常:

A JSON member value inside a JSON object must be preceded by its member name.
Run Code Online (Sandbox Code Playgroud)

这个异常来自于以下方法:

    private void EnsureMemberOnObjectBracket() 
    {
        if (_state.Bracket == JsonWriterBracket.Object)
            throw new JsonException("A JSON member value inside a JSON 
             object must be preceded by its member name.");
    }
Run Code Online (Sandbox Code Playgroud)

该代码的包含调用来自:

    public sealed override void WriteString(string value)
    {
        if (Depth == 0)
        {
            WriteStartArray(); WriteString(value); WriteEndArray();
        }
        else
        {
            EnsureMemberOnObjectBracket();
            WriteStringImpl(value);
            OnValueWritten();
        }
    }
Run Code Online (Sandbox Code Playgroud)

您的代码唯一一次调用调用的方法EnsureMemberOnObjectBracket是从一个地方:

if (m.NodeType == XmlNodeType.Text)
{ //Writes text here.  NOTE: m.Depth > lastdepth here!!!!!!!
 w.WriteString(m.Value);
 wt = true;
}
Run Code Online (Sandbox Code Playgroud)

这意味着这里有一个错误。也许你可以在这里做一些 try/catch 或改进你的代码。