【问题标题】:turn javascript array into c# array将javascript数组转换为c#数组
【发布时间】:2010-07-31 12:41:21
【问题描述】:

嘿。我有这个我要离开网络的 javascript 文件,它基本上由几个大型 javascript 数组组成。由于我是一名 .net 开发人员,我希望这个数组可以通过 c# 访问,所以我想知道是否有任何 codeplex 贡献或任何其他方法可以用来将 javascript 数组转换为我的 ac# 数组可以从我的 c# 代码中使用。

喜欢:

var roomarray = new Array(194);
var modulearray = new Array(2055);
var progarray = new Array(160);
var staffarray = new Array(3040);
var studsetarray = new Array(3221);

 function PopulateFilter(strZoneOrDept, cbxFilter) {
    var deptarray = new Array(111);
    for (var i=0; i<deptarray.length; i++) {
        deptarray[i] = new Array(1);
    }
    deptarray[0] [0] = "a/MPG - Master of Public Governance";
    deptarray[0] [1] = "a/MPG - Master of Public Governance";
    deptarray[1] [0] = "a/MBA_Flex MBA 1";
    deptarray[1] [1] = "a/MBA_Flex MBA 1";
    deptarray[2] [0] = "a/MBA_Flex MBA 2";
    deptarray[2] [1] = "a/MBA_Flex MBA 2";
    deptarray[3] [0] = "a/cand.oecon";
    deptarray[3] [1] = "a/cand.oecon";

等等

这是我忽略建议后的想法:

  1. 在我的 c# 代码中通过 httprequest 检索 javascript 文件

  2. 将它与我自己编写的一些代码粘贴在一起

  3. 从 c# 调用一个 javascript 函数的执行 selfmade 函数,该函数会将 javascript 数组转换为 json(在 json.org/json2.js 的帮助下),并将其输出到新文件

  4. 在 c# 中检索新文件,使用 DataContractJsonSerializer 解析 json,希望得到一个 c# 数组

你们觉得可行吗?

【问题讨论】:

  • 你的意思是数组是JSON格式的吗?如果你展示一个你所拥有的小例子可能会有所帮助。
  • 使用编辑器将方括号变成大括号。
  • 不幸的是它不是 JSON 格式的,它是一个 javascript 数组,我已经编辑了主要帖子以提供示例
  • 我不知道如何做到这一点(我是 JS 新手),但也许可以让 js 将数组写入文件,然后您可以从 c# 读取这些文件?
  • 你想把它变成一个 C# 类,还是从 javascript 文件中读取它作为数据文件?基本上,最终结果是 C# 类/代码还是类似 .cvs 解析器的东西?

标签: c# javascript arrays


【解决方案1】:

我现在不在使用 c# 的计算机前,因此无法完全尝试。

@Jakob 你需要做的事情如下:

  1. 编写一个解析器,它将下载文件并将其存储在内存中。
  2. 对于要“解析”为 c# 数组的每个部分(例如 zonearray),您需要设置边界以开始搜索和结束搜索文件。示例:我们知道zonearrayzonearray[i] = new Array(1); 之后的两行开始构建数组,并在zonearray.sort() 结束。
  3. 因此,有了这些界限,我们就可以在其中的每一行之间进行压缩并解析一个 C# 数组。这很简单,我认为您可以弄清楚。您还需要跟踪子索引并记住。
  4. 对每个要解析的数组重复这 2-3 步(zonearrayroomarray..etc)。

如果您不能完全弄清楚如何 对边界进行编码或如何解析行并将它们转储到数组中,我也许明天可以写点东西(即使这里是假期)在加拿大)。

编辑: 应该注意的是,您不能为此使用一些 JSON 解析器;你必须自己写。做起来并不难,你只需要把它分成小步骤(首先弄清楚如何通过每一行并找到正确的“边界”)。

HTH

编辑:我只花了大约 20 分钟为你写这篇文章。它应该解析文件并将每个数组加载到List&lt;string[]&gt; 中。我已经对它进行了大量评论,因此您可以看到发生了什么。如果您有任何问题,请不要犹豫。干杯!

private class SearchBound
{
    public string ArrayName { get; set; }
    public int SubArrayLength { get; set; }
    public string StartBound { get; set; }
    public int StartOffset { get; set; }
    public string EndBound { get; set; }
}

public static void Main(string[] args)
{
    //
    // NOTE: I used FireFox to determine the encoding that was used.
    // 

    List<string> lines = new List<string>();

    // Step 1 - Download the file and dump all the lines of the file to the list.
    var request = WebRequest.Create("http://skema.ku.dk/life1011/js/filter.js");
    using (var response = request.GetResponse())
    using(var stream = response.GetResponseStream())
    using(var reader = new StreamReader(stream, Encoding.GetEncoding("ISO-8859-1")))
    {
        string line = null;

        while ((line = reader.ReadLine()) != null)
        {
            lines.Add(line.Trim());
        }

        Console.WriteLine("Download Complete.");

    }

    var deptArrayBounds = new SearchBound
    {
        ArrayName = "deptarray",                    // The name of the JS array.
        SubArrayLength = 2,                         // In the JS, the sub array is defined as "new Array(X)" and should always be X+1 here.
        StartBound = "deptarray[i] = new Array(1);",// The line that should *start* searching for the array values.
        StartOffset = 1,                            // The StartBound + some number line to start searching the array values.
                                                    // For example: the next line might be a '}' so we'd want to skip that line.
        EndBound = "deptarray.sort();"              // The line to stop searching.
    };

    var zoneArrayBounds = new SearchBound
    {
        ArrayName = "zonearray",
        SubArrayLength = 2,
        StartBound = "zonearray[i] = new Array(1);",
        StartOffset = 1,
        EndBound = "zonearray.sort();"
    };

    var staffArrayBounds = new SearchBound
    {
        ArrayName = "staffarray",
        SubArrayLength = 3,
        StartBound = "staffarray[i] = new Array(2);",
        StartOffset = 1,
        EndBound = "staffarray.sort();"
    };

    List<string[]> deptArray = GetArrayValues(lines, deptArrayBounds);
    List<string[]> zoneArray = GetArrayValues(lines, zoneArrayBounds);
    List<string[]> staffArray = GetArrayValues(lines, staffArrayBounds);
    // ... and so on ...

    // You can then use deptArray, zoneArray etc where you want...

    Console.WriteLine("Depts: " + deptArray.Count);
    Console.WriteLine("Zones: " + zoneArray.Count);
    Console.WriteLine("Staff: " + staffArray.Count);
    Console.ReadKey();

}

private static List<string[]> GetArrayValues(List<string> lines, SearchBound bound)
{
    List<string[]> values = new List<string[]>();

    // Get the enumerator for the lines.
    var enumerator = lines.GetEnumerator();

    string line = null;

    // Step 1 - Find the starting bound line.
    while (enumerator.MoveNext() && (line = enumerator.Current) != bound.StartBound)
    {
        // Continue looping until we've found the start bound.
    }

    // Step 2 - Skip to the right offset (maybe skip a line that has a '}' ).
    for (int i = 0; i <= bound.StartOffset; i++)
    {
        enumerator.MoveNext();
    }

    // Step 3 - Read each line of the array.
    while ((line = enumerator.Current) != bound.EndBound)
    {

        string[] subArray = new string[bound.SubArrayLength];

        // Read each sub-array value.
        for (int i = 0; i < bound.SubArrayLength; i++)
        {

            // Matches everything that is between an equal sign then the value 
            // wrapped in quotes ending with a semi-colon.
            var m = Regex.Matches(line, "^(.* = \")(.*)(\";)$");

            // Get the matched value.
            subArray[i] = m[0].Groups[2].Value;

            // Move to the next sub-item if not the last sub-item.
            if (i < bound.SubArrayLength - 1)
            {
                enumerator.MoveNext();
                line = enumerator.Current;
            }
        }

        // Add the sub-array to the list of values.
        values.Add(subArray);

        // Move to the next line.
        if (!enumerator.MoveNext())
        {
            break;
        }
    }

    return values;
}

【讨论】:

  • 非常感谢您的建议,尤其是您的帮助,虽然您正在度假,但我绝不希望给您带来压力并占用您的假期。然而,就像你提到的那样,我对如何定义边界有点无能为力,所以这些方法不会变得太脆弱而无法处理这种动态文件,所以我想我将从第 1 步开始,看看如果它把我带到任何地方。
  • @TheCloudlessSky - 非常感谢 - 我会马上深入研究这个问题,然后用一枚金牌、一座雕像和一个以你命名的方尖碑回复你
  • @TheCloudlessSky - 我尝试了过滤机制,它似乎可以正常工作。然而,DL 已被证明稍微复杂一些。我在.Net 4.0中工作,其中WebRequest.GetResponse方法有问题,所以我尝试使用WebClient,但问题是js文件站点没有设置跨域策略,所以我在尝试时遇到安全错误下载文件,这就是我现在的位置。我想说你已经很好地回答了我的问题,所以如果你对我的第二期有任何建议,我会将其标记为答案并加上丹麦男爵的头衔;)
  • @Jakob - 在 SO 上发布另一个问题以获取有关错误的帮助,这样您将获得更多视图。干杯!
【解决方案2】:

如果我正确理解您的问题,您是在问是否可以从 C# 执行 JavaScript 代码,然后将结果(在您的示例中为 JavaScript Array 对象)传递给 C# 代码。

答案是:理论上当然可以,但是你需要一个真正的 JavaScript 解释器来执行 JavaScript。你必须找到一个或自己编写,但鉴于 JavaScript 是一门成熟的编程语言,为如此庞大且功能齐全的编程语言编写解释器是一项艰巨的任务,我怀疑你不会找到一个完整的现成解决方案,除非您的奉献精神超过全球所有其他 C# 和 JavaScript 死忠粉,否则您也无法编写。

但是,通过一些技巧,您可能能够强制现有的 JavaScript 解释器执行您想要的操作。由于显而易见的原因,所有浏览器都有这样的解释器,包括 Internet Explorer,您可以使用 WinForms WebBrowser 控件访问它。因此,您可以尝试以下方法:

  • 让您的 C# 代码生成一个 HTML 文件,其中包含您下载的 JavaScript 以及一些将其转换为 JSON 的 JavaScript(您似乎已经找到了这样做的东西)并将其输出到浏览器中。
  • 在 WebBrowser 控件中打开该 HTML 文件,让它执行 JavaScript,然后读回网站的内容,现在它包含了执行 JavaScript 的结果。
  • 按照您的建议,使用 DataContractJsonSerializer 将 JSON 转换为 C# 数组。

这是一个相当迂回的方法,但这是我能想到的最好的方法。

不过,我不得不怀疑,为什么您首先要从网络上检索 JavaScript 文件。是什么生成了这个 JavaScript 文件?无论生成它,肯定可以生成一些正确可读的东西(例如 XML 文件)?如果它不是由人类生成而是由人类编写的,那为什么它是用 JavaScript 而不是 XML、CSV 或其他一些数据格式编写的呢?希望有了这些想法,您可能能够找到一个不需要像上面那样使用 JavaScript 技巧的解决方案。

【讨论】:

    【解决方案3】:

    最简单的解决方案是只执行创建数组的 Javascript 函数。包括一个使它成为 JSON (http://www.json.org/js.html) 的函数。之后向服务器发出 XMLHttpRequest (AJAX) 并从那里将 JSON 提取到自定义类。

    如果我可以使用 jQuery,这里是所需 Javascript 的示例:

    var myJSONText = JSON.stringify(deptarray);
    (function($){
        $.ajax({
            type: "POST",
            url: "some.aspx",
            data: myJSONText,
            success: function(msg){
                alert( "Data Saved: " + msg );
            }
        });
    })(jQuery);
    

    现在只需要一些代码将 JSON 字符串转换为 C# 数组。

    编辑:
    看了一圈,找到了Json.NET:http://json.codeplex.com/
    Stackoverflow 上也有很多相同的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-01
      • 2013-02-12
      • 2020-04-30
      • 2014-07-13
      • 2013-05-26
      • 2011-08-02
      • 2015-09-22
      • 2018-12-16
      相关资源
      最近更新 更多