解决 如何不使用索引从JSON中的元素获取值?

WeyardWiz

成员
已加入
2020年10月23日
留言内容
23
编程经验
3-5
我有以下代码提取json元素值并将其输出到csv:

C#:
public static void Json_to_Csv(string jsonInputFile, string csvFile)
{
    using (var p = new ChoJSONReader(jsonInputFile).WithJSONPath("$..readResults")) // "readResults": [
    {
        using (var w = new ChoCSVWriter(csvFile).WithFirstLineHeader())
        {
            w.Write(p
                .Select(r1 =>
                {
                    var lines = (dynamic[])r1.lines;
                    return new
                    {
                        FileName = jsonInputFile,
                        Page = r1.page,
                        PracticeName = lines[2].text,
                        OwnerFullName = lines[4].text,
                        OwnerEmail = lines[6].text,
                    };
                }
        }
    }
}

csv输出:

文件名,页面,实践名称,所有者全名,所有者电子邮件
file1.json,1,Some Practice Name,Bob Lee,鲍勃@ someemail.com

当前在每个项目上没有其他上下文信息可以引用它们,因此唯一的方法是通过索引,例如线[2]

现在可以使用,但是我可能还有其他具有额外字段的JSON文件,因此提取的值将是错误的。

为了解决这种情况, 我如何在上下文中拉取值而不是对行进行索引?

我试过了
C#:
PracticeName = lines["Practice Name"].text

但我明白了 无法将类型字符串隐式转换为int error


file1.json示例:

JSON:
{
  "status": "succeeded",
  "createdDateTime": "2020-10-22T19:35:35Z",
  "lastUpdatedDateTime": "2020-10-22T19:35:36Z",
  "analyzeResult": {
    "version": "3.0.0",
    "readResults": [
      {
        "page": 1,
        "angle": 0,
        "width": 8.5,
        "height": 11,
        "unit": "inch",
        "lines": [        
          {
            "boundingBox": [
              0.5016,
              1.9141,
              2.5726,
              1.9141,
              2.5726,
              2.0741,
              0.5016,
              2.0741
            ],          
           "text": "Account Information",
            "words": [
              {
                "boundingBox": [
                  0.5016,
                  1.9345,
                  1.3399,
                  1.9345,
                  1.3399,
                  2.0741,
                  0.5016,
                  2.0741
                ],
                "text": "Account",
                "confidence": 1
              },
              {
                "boundingBox": [
                  1.3974,
                  1.9141,
                  2.5726,
                  1.9141,
                  2.5726,
                  2.0741,
                  1.3974,
                  2.0741
                ],
                "text": "Information",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              1.7716,
              2.4855,
              2.8793,
              2.4855,
              2.8793,
              2.6051,
              1.7716,
              2.6051
            ],
            "text": "Practice Name",
            "words": [
              {
                "boundingBox": [
                  1.7716,
                  2.4855,
                  2.3803,
                  2.4855,
                  2.3803,
                  2.6051,
                  1.7716,
                  2.6051
                ],
                "text": "Practice",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4362,
                  2.4948,
                  2.8793,
                  2.4948,
                  2.8793,
                  2.6051,
                  2.4362,
                  2.6051
                ],
                "text": "Name",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              2.9993,
              2.5257,
              4.7148,
              2.5257,
              4.7148,
              2.714,
              2.9993,
              2.714
            ],
            "text": "Some Practice Name",
            "words": [
              {
                "boundingBox": [
                  3.0072,
                  2.5385,
                  3.6546,
                  2.5284,
                  3.6516,
                  2.7131,
                  3.0105,
                  2.712
                ],
                "text": "Some",
                "confidence": 0.984
              },
              {
                "boundingBox": [
                  3.6887,
                  2.5281,
                  4.2112,
                  2.5262,
                  4.2028,
                  2.7159,
                  3.6854,
                  2.7132
                ],
                "text": "Parctice",
                "confidence": 0.986
              },
              {
                "boundingBox": [
                  4.2453,
                  2.5263,
                  4.7223,
                  2.5297,
                  4.7091,
                  2.72,
                  4.2366,
                  2.7161
                ],
                "text": "Name",
                "confidence": 0.986
              }
            ]
          },
          {
            "boundingBox": [
              1.6116,
              2.9999,
              2.8816,
              2.9999,
              2.8816,
              3.1158,
              1.6116,
              3.1158
            ],
            "text": "Owner Full Name",
            "words": [
              {
                "boundingBox": [
                  1.6116,
                  3.0039,
                  2.1026,
                  3.0039,
                  2.1026,
                  3.1157,
                  1.6116,
                  3.1157
                ],
                "text": "Owner",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.1541,
                  2.9999,
                  2.3784,
                  2.9999,
                  2.3784,
                  3.1158,
                  2.1541,
                  3.1158
                ],
                "text": "Full",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4384,
                  3.0052,
                  2.8816,
                  3.0052,
                  2.8816,
                  3.1155,
                  2.4384,
                  3.1155
                ],
                "text": "Name",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              2.9993,
              3.0242,
              3.6966,
              3.0242,
              3.6966,
              3.2125,
              2.9993,
              3.2014
            ],
            "text": "Bob Lee",
            "words": [
              {
                "boundingBox": [
                  3.0063,
                  3.0303,
                  3.3439,
                  3.0349,
                  3.3461,
                  3.2125,
                  3.007,
                  3.2081
                ],
                "text": "Bob",
                "confidence": 0.987
              },
              {
                "boundingBox": [
                  3.3788,
                  3.0349,
                  3.6931,
                  3.0326,
                  3.697,
                  3.2121,
                  3.3813,
                  3.2125
                ],
                "text": "Lee",
                "confidence": 0.983
              }
            ]
          },
          {
            "boundingBox": [
              1.945,
              3.5063,
              2.8748,
              3.5063,
              2.8748,
              3.6261,
              1.945,
              3.6261
            ],
            "text": "Owner Email",
            "words": [
              {
                "boundingBox": [
                  1.945,
                  3.5143,
                  2.4359,
                  3.5143,
                  2.4359,
                  3.6261,
                  1.945,
                  3.6261
                ],
                "text": "Owner",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4874,
                  3.5063,
                  2.8748,
                  3.5063,
                  2.8748,
                  3.6259,
                  2.4874,
                  3.6259
                ],
                "text": "Email",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              3.0104,
              3.5005,
              4.6042,
              3.5005,
              4.6042,
              3.6888,
              3.0104,
              3.6777
            ],
            "text": "[email protected]",
            "words": [
              {
                "boundingBox": [
                  3.0212,
                  3.5047,
                  4.5837,
                  3.5039,
                  4.5769,
                  3.6886,
                  3.0129,
                  3.6787
                ],
                "text": "[email protected]",
                "confidence": 0.951
              }
            ]
          }
        ]
      }
    ]
  }
}
 
由主持人最后编辑:
Solution
以下将对输出到控制台:
C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;

class RootObject
{
    [JsonProperty("analyzeResult")]
    public AnalyzeResult AnalyzeResult { get; set; }
}

class AnalyzeResult
{
    [JsonProperty("readResults")]
    public ReadResults[] ReadResults { get; set; }
}

class ReadResults
{
    [JsonProperty("lines")]
    public Line[] Lines { get; set; }
}

class Line
{
    [JsonProperty("text")]
    public string Text { get; set; }

    public override string ToString() => Text;
}

public static class IEnumerableExtensions
{
    public static IEnumerable<KeyValuePair<T, T>> Pairs<T>(this IEnumerable<T> items)
    {...

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,523
地点
弗吉尼亚州切萨皮克
编程经验
10+
您将使用LINQ to Objects过滤到所需的对象实例。这很重要,您需要将JSON反序列化为对象。我不熟悉ChoJSONReader,但我知道我已经不喜欢它,因为它不遵循.NET Framework的命名约定。
 

WeyardWiz

成员
已加入
2020年10月23日
留言内容
23
编程经验
3-5
您将使用LINQ to Objects过滤到所需的对象实例。这很重要,您需要将JSON反序列化为对象。我不熟悉ChoJSONReader,但我知道我已经不喜欢它,因为它不遵循.NET Framework的命名约定。
我尝试遵循反序列化方法,但是对于我想做的事情,实现起来似乎太复杂了。我发现ChoJSONReader可作为替代方案,因为到目前为止,它是实现我想要的目标的唯一方法。
如果您能给我看一个上面提到的例子,我将不胜感激,因为这可能有助于改善我目前的设计,并使事情变得更加灵活。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
如果您知道文件的内容,则可以将数据填充到一个类中。从该类中,您可以轻松地将其序列化为csv文件。我向跳伞运动员展示另一个主题的一种方法是填充方法: 填充对象 他承认这很有用。 序列化反序列化 可以在这些页面上找到其他有用的示例。
 

WeyardWiz

成员
已加入
2020年10月23日
留言内容
23
编程经验
3-5
如果您知道文件的内容,则可以将数据填充到一个类中。从该类中,您可以轻松地将其序列化为csv文件。我向跳伞运动员展示另一个主题的一种方法是填充方法: 填充对象 他承认这很有用。 序列化反序列化 可以在这些页面上找到其他有用的示例。
通常情况下,我们将拥有一个属性,然后为其赋予一个值,如下所示:

C#:
public string Test { get; set; }

        public Program()

        {

            Test = "Test";

        }

然后,我们可以在其他位置基于属性名称获取值。

但是在这个json中,"Owner Full Name" and "Bob Lee"不是属性和值之间的关系,而是两个不相关对象中Text属性的值,如下所示:

C#:
public class Line

    {

        public float[] BoundingBox { get; set; }

        public string Text { get; set; }

        public Word[] Words { get; set; }

    }

 

    ***********************



    new Line() { Text = "Owner Full Name" };

    new Line() { Text = "Bob Lee" };

除了在我的原始代码中手动指定外,我们无法在它们之间建立连接。

因此,在尝试将id导入到csv文件之前,id必须重建一个合格的JSON,但是问题在于此json是来自Azure计算机视觉读取API响应的结果。

我猜我当前使用choJSON的代码是完成此操作的唯一方法。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
如果您不愿意阅读我给您提供的链接上的文档,您将发现它是不可能而且非常容易的。
 

WeyardWiz

成员
已加入
2020年10月23日
留言内容
23
编程经验
3-5
如果您不愿意阅读我给您提供的链接上的文档,您将发现它是不可能而且非常容易的。
我看过了
填充对象在它们显示的Account类示例中起作用,因为它是属性/值关系。因此,非常容易地对其进行动态反序列化。但是,在我发布的json中,此方法不起作用,因为属性和假定的“值”没有连接。作为人类,我可以说“ Bob Lee”是“所有者全名”属性的值,但是程序无法像我一样区分。因为它们之间没有联系。

唯一的方法是手动为每个文件填充一个类,这违背了使用程序执行此操作的目的,因为我可以通过读取原始pdf文件直接在csv中手动填充数据。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,523
地点
弗吉尼亚州切萨皮克
编程经验
10+
查看那里的JSON,看起来它大致映射到以下类结构:
C#:
class RootObject
{
    AnalyzeResult AnalyzeResult { get; set; }
}

class AnalyzeResult
{
    ReadResults ReadResults { get; set; }
}

class ReadResults
{
    Line [] Lines { get; set; }
}

class Line
{
    string Text { get; set; }
    Word [] Words { get; set; }
}

class Word
{
    string Text { get; set; }
}

如果您知道每对线始终是一个名称/值对,则只需将线对成对并设置值以输出到CSV中即可。

顺便说一句,我浏览了GitHub中的ChoJSONReader的源代码。它只是NewtonSoft JSON.NET库的包装。
 

WeyardWiz

成员
已加入
2020年10月23日
留言内容
23
编程经验
3-5
有趣的...您可以演示“将线成对地浸入并设置要放入CSV的值”吗?我认为迫使我使用choJSONReader的原因是choCSVWriter,因为最终这就是我想要的,将属性/值写入csv。
如果这只是JSON.NET库的包装,是否意味着有可能 在上下文中拉取值而不是对行进行索引?如果是这样,怎么办?

Mod编辑:无需整体引用或直接引用您上方的人。
 
由主持人最后编辑:

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,523
地点
弗吉尼亚州切萨皮克
编程经验
10+
以下将对输出到控制台:
C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Newtonsoft.Json;

class RootObject
{
    [JsonProperty("analyzeResult")]
    public AnalyzeResult AnalyzeResult { get; set; }
}

class AnalyzeResult
{
    [JsonProperty("readResults")]
    public ReadResults[] ReadResults { get; set; }
}

class ReadResults
{
    [JsonProperty("lines")]
    public Line[] Lines { get; set; }
}

class Line
{
    [JsonProperty("text")]
    public string Text { get; set; }

    public override string ToString() => Text;
}

public static class IEnumerableExtensions
{
    public static IEnumerable<KeyValuePair<T, T>> Pairs<T>(this IEnumerable<T> items)
    {
        var enumerator = items.GetEnumerator();

        while (enumerator.MoveNext())
        {
            var name = enumerator.Current;
            if (enumerator.MoveNext())
                yield return new KeyValuePair<T, T>(name, enumerator.Current);
            else
                throw new InvalidDataException("Odd number of items found in IEnumerable<T>");
        }
    }
}

class Program
{
    static IEnumerable<Line> GetLines(string jsonText)
    {
        var root = JsonConvert.DeserializeObject<RootObject>(jsonText);
        return root.AnalyzeResult
                   .ReadResults
                   .SelectMany(r => r.Lines);
    }

    static void Main(string[] args)
    {
        var lines = GetLines(File.ReadAllText("response.json"));

        // Skip(1) to skip over the "Account Information" Line.
        var pairs = lines.Skip(1).Pairs();

        foreach(var pair in pairs)
            Console.WriteLine($"{pair.Key}: {pair.Value}");
    }
}

产生以下输出:
Code:
练习名称:一些练习名称 
店主全名:Bob Lee
Owner Email: [email protected]
 
Last edited:
解决方案

WeyardWiz

成员
已加入
2020年10月23日
留言内容
23
编程经验
3-5
以下将对输出到控制台:
C#:
    static void Main(string[] args)
    {
        // Skip(1) to skip over the "Account Information" Line.
        var pairs = lines.Skip(1).Pairs();
    }
太棒了,谢谢跳伞运动员。虽然,我不必显式跳过某条线的事实,即"Account Information",是否意味着Im在技术上仍限于JSON结构?换句话说,这是否意味着如果我有另一个JSON文件结构,其中甚至在Account Information之前都有更多字段,那么我将不得不再次调整跳过以确保其读取的第一个字段是Practice Name?
有没有办法使它更具动态性,以便直接转到“练习名称”,而不必只跳过一定数量的行?
就像是:
C#:
var pairs = lines.SkipAllUntil("Practice Name").Pairs();
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,523
地点
弗吉尼亚州切萨皮克
编程经验
10+
I only put in the skip there as hard coded because I was trying to highlight the pulling of JSON elements in pairs since that is what you asked about. With software anything is possible. It just depends how much time, energy, and money you want to invest. To answer your new question, you can operate on any IEnumerable using LINQ's SkipWhile().
 

WeyardWiz

成员
已加入
2020年10月23日
留言内容
23
编程经验
3-5
I only put in the skip there as hard coded because I was trying to highlight the pulling of JSON elements in pairs since that is what you asked about. With software anything is possible. It just depends how much time, energy, and money you want to invest. To answer your new question, you can operate on any IEnumerable using LINQ's SkipWhile().
我知道了。因此,香港专业教育学院尝试以下方法:
C#:
var pairs = lines.SkipWhile(r => r == "Practice Name").Pairs();
但是我越来越 "运算符'=='不能应用于'Line'和'String'类型的操作数"

我想我理解此错误的含义,因为Line不是String类型,无法进行这样的直接比较。

香港专业教育学院想好了,很容易,我只是要将行转换为字符串类型:
C#:
var pairs = lines.SkipWhile(r => r.ToString() == "Practice Name").Pairs();

但是,这不仅打印出来"Account Information",但配对在控制台输出上变得混乱,然后出现异常
"无法访问的代码,“在IEnumerable中发现奇数个项目<T>'"

但是无论如何,这是否意味着必须总是使用==行才能使用while练习名称?这意味着只有部分JSON被执行?

请原谅我提出了很多问题,我用C#编程的最后一次是6年前,而香港专业教育学院最近不得不再次使用它。不过,到现在为止,真的很感谢您的指导!
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,523
地点
弗吉尼亚州切萨皮克
编程经验
10+
翻转逻辑。
C#:
var pairs = lines.SkipWhile(l => l.Text != "Practice Name").Pairs();
foreach(var pair in pairs)
    Console.WriteLine($"{pair.Key}: {pair.Value}");
似乎对我来说是对的。
 

WeyardWiz

成员
已加入
2020年10月23日
留言内容
23
编程经验
3-5
Flip the logic.
C#:
var pairs = lines.SkipWhile(l => l.Text != "Practice Name").Pairs();
foreach(var pair in pairs)
    Console.WriteLine($"{pair.Key}: {pair.Value}");
似乎对我来说是对的。
太棒了,确实可以解决问题 :)
顺便说一句,此JSON结构是通过以下方式生成的 Azure计算机视觉REST API 从这样的pdf输入中:

1603905939908.png


我之所以这样说,是因为我了解IEnumerable代码在做什么,但是有一种极端情况可能与它的工作方式不符。基本上,我的理解是:

扫描JSON似乎表明奇数行的.text是字段的名称
偶数行的.text是该字段的值。
例如:
如果lines [3] .text是"Owner Full Name",
那么第[3 + 1]行是"Bob Lee"

跳过的变量将是感兴趣区域之前的所有内容的“行”输入
删除。然后,我们仅跳过字段名称行并返回下一行的.text属性。

API将图片/ pdf中的完整JSON导出为:

JSON:
{
  "status": "succeeded",
  "createdDateTime": "2020-10-22T19:35:35Z",
  "lastUpdatedDateTime": "2020-10-22T19:35:36Z",
  "analyzeResult": {
    "version": "3.0.0",
    "readResults": [
      {
        "page": 1,
        "angle": 0,
        "width": 8.5,
        "height": 11,
        "unit": "inch",
        "lines": [       
          {
            "boundingBox": [
              0.5016,
              1.9141,
              2.5726,
              1.9141,
              2.5726,
              2.0741,
              0.5016,
              2.0741
            ],         
           "text": "Account Information",
            "words": [
              {
                "boundingBox": [
                  0.5016,
                  1.9345,
                  1.3399,
                  1.9345,
                  1.3399,
                  2.0741,
                  0.5016,
                  2.0741
                ],
                "text": "Account",
                "confidence": 1
              },
              {
                "boundingBox": [
                  1.3974,
                  1.9141,
                  2.5726,
                  1.9141,
                  2.5726,
                  2.0741,
                  1.3974,
                  2.0741
                ],
                "text": "Information",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              1.7716,
              2.4855,
              2.8793,
              2.4855,
              2.8793,
              2.6051,
              1.7716,
              2.6051
            ],
            "text": "Practice Name",
            "words": [
              {
                "boundingBox": [
                  1.7716,
                  2.4855,
                  2.3803,
                  2.4855,
                  2.3803,
                  2.6051,
                  1.7716,
                  2.6051
                ],
                "text": "Practice",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4362,
                  2.4948,
                  2.8793,
                  2.4948,
                  2.8793,
                  2.6051,
                  2.4362,
                  2.6051
                ],
                "text": "Name",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              2.9993,
              2.5257,
              4.7148,
              2.5257,
              4.7148,
              2.714,
              2.9993,
              2.714
            ],
            "text": "Some Practice Name",
            "words": [
              {
                "boundingBox": [
                  3.0072,
                  2.5385,
                  3.6546,
                  2.5284,
                  3.6516,
                  2.7131,
                  3.0105,
                  2.712
                ],
                "text": "Some",
                "confidence": 0.984
              },
              {
                "boundingBox": [
                  3.6887,
                  2.5281,
                  4.2112,
                  2.5262,
                  4.2028,
                  2.7159,
                  3.6854,
                  2.7132
                ],
                "text": "Practice",
                "confidence": 0.986
              },
              {
                "boundingBox": [
                  4.2453,
                  2.5263,
                  4.7223,
                  2.5297,
                  4.7091,
                  2.72,
                  4.2366,
                  2.7161
                ],
                "text": "Name",
                "confidence": 0.986
              }
            ]
          },
          {
            "boundingBox": [
              1.6116,
              2.9999,
              2.8816,
              2.9999,
              2.8816,
              3.1158,
              1.6116,
              3.1158
            ],
            "text": "Owner Full Name",
            "words": [
              {
                "boundingBox": [
                  1.6116,
                  3.0039,
                  2.1026,
                  3.0039,
                  2.1026,
                  3.1157,
                  1.6116,
                  3.1157
                ],
                "text": "Owner",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.1541,
                  2.9999,
                  2.3784,
                  2.9999,
                  2.3784,
                  3.1158,
                  2.1541,
                  3.1158
                ],
                "text": "Full",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4384,
                  3.0052,
                  2.8816,
                  3.0052,
                  2.8816,
                  3.1155,
                  2.4384,
                  3.1155
                ],
                "text": "Name",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              2.9993,
              3.0242,
              3.6966,
              3.0242,
              3.6966,
              3.2125,
              2.9993,
              3.2014
            ],
            "text": "Bob Lee",
            "words": [
              {
                "boundingBox": [
                  3.0063,
                  3.0303,
                  3.3439,
                  3.0349,
                  3.3461,
                  3.2125,
                  3.007,
                  3.2081
                ],
                "text": "Bob",
                "confidence": 0.987
              },
              {
                "boundingBox": [
                  3.3788,
                  3.0349,
                  3.6931,
                  3.0326,
                  3.697,
                  3.2121,
                  3.3813,
                  3.2125
                ],
                "text": "Lee",
                "confidence": 0.983
              }
            ]
          },
          {
            "boundingBox": [
              1.945,
              3.5063,
              2.8748,
              3.5063,
              2.8748,
              3.6261,
              1.945,
              3.6261
            ],
            "text": "Owner Email",
            "words": [
              {
                "boundingBox": [
                  1.945,
                  3.5143,
                  2.4359,
                  3.5143,
                  2.4359,
                  3.6261,
                  1.945,
                  3.6261
                ],
                "text": "Owner",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4874,
                  3.5063,
                  2.8748,
                  3.5063,
                  2.8748,
                  3.6259,
                  2.4874,
                  3.6259
                ],
                "text": "Email",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              3.0104,
              3.5005,
              4.6042,
              3.5005,
              4.6042,
              3.6888,
              3.0104,
              3.6777
            ],
            "text": "[email protected]",
            "words": [
              {
                "boundingBox": [
                  3.0212,
                  3.5047,
                  4.5837,
                  3.5039,
                  4.5769,
                  3.6886,
                  3.0129,
                  3.6787
                ],
                "text": "[email protected]",
                "confidence": 0.951
              }
            ]
          },
          {
            "boundingBox": [
              1.945,
              6.5768,
              2.8886,
              6.5768,
              2.8886,
              6.7271,
              1.945,
              6.7271
            ],
            "text": "Server Setup",
            "words": [
              {
                "boundingBox": [
                  1.945,
                  6.5768,
                  2.4165,
                  6.5768,
                  2.4165,
                  6.6884,
                  1.945,
                  6.6884
                ],
                "text": "Server",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.4643,
                  6.5768,
                  2.8886,
                  6.5768,
                  2.8886,
                  6.7271,
                  2.4643,
                  6.7271
                ],
                "text": "Setup",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              3.5085,
              6.5025,
              3.7298,
              6.5136,
              3.7188,
              6.7351,
              3.4974,
              6.7241
            ],
            "text": "V",
            "words": [
              {
                "boundingBox": [
                  3.5672,
                  6.5046,
                  3.7293,
                  6.5128,
                  3.7183,
                  6.734,
                  3.5561,
                  6.7259
                ],
                "text": "V",
                "confidence": 0.984
              }
            ]
          },
          {
            "boundingBox": [
              3.7471,
              6.6145,
              4.1792,
              6.6145,
              4.1792,
              6.7304,
              3.7471,
              6.7304
            ],
            "text": "Cloud",
            "words": [
              {
                "boundingBox": [
                  3.7471,
                  6.6145,
                  4.1792,
                  6.6145,
                  4.1792,
                  6.7304,
                  3.7471,
                  6.7304
                ],
                "text": "Cloud",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              4.904,
              6.6105,
              5.5344,
              6.6105,
              5.5344,
              6.7301,
              4.904,
              6.7301
            ],
            "text": "Location",
            "words": [
              {
                "boundingBox": [
                  4.904,
                  6.6105,
                  5.5344,
                  6.6105,
                  5.5344,
                  6.7301,
                  4.904,
                  6.7301
                ],
                "text": "Location",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              6.2924,
              6.6037,
              7.8618,
              6.6037,
              7.8618,
              6.752,
              6.2924,
              6.752
            ],
            "text": "Central (multi-location)",
            "words": [
              {
                "boundingBox": [
                  6.2924,
                  6.6145,
                  6.8385,
                  6.6145,
                  6.8385,
                  6.7301,
                  6.2924,
                  6.7301
                ],
                "text": "Central",
                "confidence": 1
              },
              {
                "boundingBox": [
                  6.8929,
                  6.6037,
                  7.8618,
                  6.6037,
                  7.8618,
                  6.752,
                  6.8929,
                  6.752
                ],
                "text": "(multi-location)",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              0.6466,
              7.0788,
              2.8775,
              7.0788,
              2.8775,
              7.2388,
              0.6466,
              7.2388
            ],
            "text": "Number of Locations Enrolling",
            "words": [
              {
                "boundingBox": [
                  0.6466,
                  7.0832,
                  1.2496,
                  7.0832,
                  1.2496,
                  7.1991,
                  0.6466,
                  7.1991
                ],
                "text": "Number",
                "confidence": 1
              },
              {
                "boundingBox": [
                  1.2969,
                  7.0788,
                  1.4364,
                  7.0788,
                  1.4364,
                  7.1988,
                  1.2969,
                  7.1988
                ],
                "text": "of",
                "confidence": 1
              },
              {
                "boundingBox": [
                  1.4892,
                  7.0793,
                  2.2013,
                  7.0793,
                  2.2013,
                  7.1988,
                  1.4892,
                  7.1988
                ],
                "text": "Locations",
                "confidence": 1
              },
              {
                "boundingBox": [
                  2.2576,
                  7.0793,
                  2.8775,
                  7.0793,
                  2.8775,
                  7.2388,
                  2.2576,
                  7.2388
                ],
                "text": "Enrolling",
                "confidence": 1
              }
            ]
          },
          {
            "boundingBox": [
              3.4421,
              7.0342,
              3.6413,
              7.0453,
              3.6413,
              7.3001,
              3.4421,
              7.289
            ],
            "text": "1",
            "words": [
              {
                "boundingBox": [
                  3.4757,
                  7.0352,
                  3.6451,
                  7.0446,
                  3.631,
                  7.299,
                  3.4616,
                  7.2896
                ],
                "text": "1",
                "confidence": 0.987
              }
            ]
          },
          {
            "boundingBox": [
              4.1835,
              7.0896,
              7.8999,
              7.0896,
              7.8999,
              7.2158,
              4.1835,
              7.2158
            ],
            "text": "*If more than 1 location, add info on the locations form",
            "words": [
              {
                "boundingBox": [
                  4.1835,
                  7.0896,
                  4.3291,
                  7.0896,
                  4.3291,
                  7.1979,
                  4.1835,
                  7.1979
                ],
                "text": "*If",
                "confidence": 1
              },
              {
                "boundingBox": [
                  4.3611,
                  7.1193,
                  4.725,
                  7.1193,
                  4.725,
                  7.1988,
                  4.3611,
                  7.1988
                ],
                "text": "more",
                "confidence": 1
              },
              {
                "boundingBox": [
                  4.7701,
                  7.0936,
                  5.0809,
                  7.0936,
                  5.0809,
                  7.1988,
                  4.7701,
                  7.1988
                ],
                "text": "than",
                "confidence": 1
              },
              {
                "boundingBox": [
                  5.1307,
                  7.0985,
                  5.1613,
                  7.0985,
                  5.1613,
                  7.1979,
                  5.1307,
                  7.1979
                ],
                "text": "1",
                "confidence": 1
              },
              {
                "boundingBox": [
                  5.2006,
                  7.09,
                  5.7803,
                  7.09,
                  5.7803,
                  7.2158,
                  5.2006,
                  7.2158
                ],
                "text": "location,",
                "confidence": 1
              },
              {
                "boundingBox": [
                  5.8268,
                  7.0936,
                  6.102,
                  7.0936,
                  6.102,
                  7.1988,
                  5.8268,
                  7.1988
                ],
                "text": "add",
                "confidence": 1
              },
              {
                "boundingBox": [
                  6.1394,
                  7.0896,
                  6.3896,
                  7.0896,
                  6.3896,
                  7.1988,
                  6.1394,
                  7.1988
                ],
                "text": "info",
                "confidence": 1
              },
              {
                "boundingBox": [
                  6.435,
                  7.1193,
                  6.6005,
                  7.1193,
                  6.6005,
                  7.1988,
                  6.435,
                  7.1988
                ],
                "text": "on",
                "confidence": 1
              },
              {
                "boundingBox": [
                  6.6481,
                  7.0936,
                  6.865,
                  7.0936,
                  6.865,
                  7.1988,
                  6.6481,
                  7.1988
                ],
                "text": "the",
                "confidence": 1
              },
              {
                "boundingBox": [
                  6.9081,
                  7.09,
                  7.5365,
                  7.09,
                  7.5365,
                  7.1988,
                  6.9081,
                  7.1988
                ],
                "text": "locations",
                "confidence": 1
              },
              {
                "boundingBox": [
                  7.5783,
                  7.0896,
                  7.8999,
                  7.0896,
                  7.8999,
                  7.1988,
                  7.5783,
                  7.1988
                ],
                "text": "form",
                "confidence": 1
              }
            ]
          }
        ]
      }
    ]
  }
}

我认为该API并不完美,因此在边界框中涉及多个元素时,我们会遇到一些麻烦。例如,API的解释方式"Server Setup"和它解释的一样"Owner Full Name",基本上只是遵循这样的约定:奇数行的.text是字段的名称,偶数行的.text是该字段的值。
它无法放置所谓的"values"那个领域的"inner"内的有界框"Server Setup"文本,因此我们最终得到这样的输出:

练习名称:一些练习名称
所有者全名: Bob Lee
所有者电子邮件: [email protected]
服务器设置: V
云:位置
中央(多地点):注册地点的数量
1:*如果位置不止一个,请在位置表格中添加信息

尽管“练习名称”,“所有者”,“全名”和“所有者电子邮件”字段/值正确,但是“服务器设置”字段和值却不正确。这是可以理解的,因为JSON结构就像开头那样,缺少一个"child"类元素的依赖关系,否则我们会在pdf / image中观察到。

1603906337179.png


笔记:"V"表示该复选标记,因为该API似乎无法将符号解释为JSON。

但是理想的输出应该是这样的:

练习名称:一些练习名称
所有者全名: Bob Lee
所有者电子邮件: [email protected]
服务器设置: Cloud
位置:中央(多位置)
地点数 Enrolling: 1

如何调整IEnumerable代码以适应这种边缘情况(如果可能的话)?
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,523
地点
弗吉尼亚州切萨皮克
编程经验
10+
回想一下帖子8,我说:
如果您知道每对线始终是一个名称/值对,则只需将线对成对并设置值以输出到CSV中即可。

您的数据不符合该条件。

花时间阅读有关LINQ流水线和流畅接口如何工作的信息。您可以添加额外的过滤器和修饰符,以更改数据沿管道向下流动的方式,并尝试调整字段的枚举。

就我个人而言,我认为您使用错误的方法先执行OCR,然后再尝试对输出的数据进行处理。我的建议是先对扫描的PDF或纸张进行AI分类,然后将不同形式的表格分类为特定类型的存储桶。然后,对于每个存储桶,您将应用“策略”模式,并具有一个与OCR一起使用的自定义掩码,以仅扫描对您重要的数据。然后,当每个存储桶中的数据出来时,它会被馈入POCO,这是您最终希望保存到CSV的正确数据形状。我的直觉说,您必须以任何一种方式走这条路,因为在某些形式可能会说出的地方会有差异"Owner Full Name",而其他形式将"Owner's Name", or just "Name". And other forms may have the different fields in different orders (and so that SkipWhile() will end up skipping over important data. Consider what happens when you have to deal with languages that are RTL, where the field labels will be on the right and the values will be on the left.
 

WeyardWiz

成员
已加入
2020年10月23日
留言内容
23
编程经验
3-5
您的数据不符合该条件。

花时间阅读有关LINQ流水线和流畅接口如何工作的信息。您可以添加额外的过滤器和修饰符,以更改数据沿管道向下流动的方式,并尝试调整字段的枚举。
因为有些表格可能会说出差异"Owner Full Name",而其他形式将"Owner's Name", or just "Name". And other forms may have the different fields in different orders (and so that SkipWhile() will end up skipping over important data. Consider what happens when you have to deal with languages that are RTL, where the field labels will be on the right and the values will be on the left.
这是非常好的一点。 Ive与团队进行了审查,他们说此表格将是官方模板,因此我们不必担心差异。
既然是这种情况,从JSON寻找所需的输出即时消息是否仍不满足post#8中的条件?换句话说,以上代码仅适用于满足该条件的JSON项目,例如所有者全名?
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,523
地点
弗吉尼亚州切萨皮克
编程经验
10+
即使没有差异,数据仍然不满足相邻线对彼此相关的条件。这"Server Setup"后面紧接4条与之相关的线。这"Number of Locations"有2条线与此相关。
 

约翰·H

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
1,040
地点
挪威
编程经验
10+
也许尝试将线按boundingBox中的第二个数字分组(似乎是线Y坐标),则需要+ -0.12的接近度比较,请参见 LINQ(或伪代码)按接近程度对项目进行分组
然后,您可以处理每个组,其中第一个文本为标签,第二个为值。这"Server Setup"该行将需要特殊处理,以找出跟随"V" selection.
 

约翰·H

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
1,040
地点
挪威
编程经验
10+
按照我的建议,这增加了 @跳伞在第10页中的代码。
Line class:
[JsonProperty("boundingBox")]
public double[] BoundingBox { get; set; }
IEnumerableExtensions:
internal static IEnumerable<IEnumerable<Line>> GroupByProximity(this IEnumerable<Line> source, double threshold)
{
    var g = new List<Line>();
    foreach (var x in source)
    {
        if ((g.Count != 0) && (!x.BoundingBox[1].IsProximity(g[0].BoundingBox[1], threshold)))
        {
            yield return g;
            g = new List<Line>();
        }
        g.Add(x);
    }
    yield return g;
}

private static bool IsProximity(this double value, double compareTo, double treshold) {
    return value >= compareTo - treshold && value <= compareTo + treshold;
}
example usage:
var lines = GetLines(File.ReadAllText("response.json"));
var groups = lines.GroupByProximity(0.12);

var dictionary = groups.ToDictionary(g => g.First().Text, g => g.Skip(1).Select(line => line.Text));
var value1 = dictionary["Practice Name"].First();
var value2 = dictionary["Server Setup"].SkipWhile(s => s != "V").Skip(1).FirstOrDefault();
var value3 = string.Join(" ", dictionary["Number of Locations Enrolling"]);
ToDictionary要求标签是不同的,如果不是,则可以使用ToLookup。
value2 example不允许选择,在这种情况下将为null。
value3 仅仅是将所有行值组合到单个字符串中的示例。
 
最佳 底部