简单的问题,到目前为止,我还没有轻易找到答案。 (类似的问题建议我输入这一点并不相关 - 但我不能相信我是唯一面临这一挑战的人。)
说我在内存中有一个包含
的对象序列化这些是有道理的
但这意味着我最终得到了两个文件。如果所有信息都在一个文件中则更好,因此读者可以明确地理解(2)来自(1)的结果。也更容易在文件系统中维护。
我不想组合成BLOB,因为这会失去人类的可读性。
是否有一种简单的方法可以将(1)中的JSON和(2)的CSV组合成一个文件?
我的第一个猜测是让(比方说)XML标签分隔不同的类型。 e.g。
<SimpleTypes format="JSON">
[JSON for simple types]
</SimpleTypes>
<Collection format="CSV" type="Dictionary" name="DailySalesTotal">
[CSV for collection]
</Collection>
<Collection format="CSV" type="Dictionary" name="DailyFootfallInStore">
[CSV for collection]
</Collection>
然后只需打开文件,将XML解析为单独的JSON和CSV部分并正常处理。
这是一种明智的做法吗?有风险吗?
或者这里有图书馆吗?我使用C#所以需要一个.NET库。
答案 0 :(得分:1)
我挑战了为什么这会有意义的原因。
主要是,提议的使用XML的解决方案只是使用另一种序列化格式。让我们看看我们是否能达到既定目标:
与YAML合作。借用您的示例,假设我们将为每个条目保存不必要的标签重复
name
和computer_name
作为“简单”数据,并将一些数据附加为“集合数据”< / em>的。琐碎的方法看起来像这样:
name: My Name
computer_name: My Computer
collection:
- time: 1:30
data: foo
- time: 2:20
data: bar
不涉及重复标签。当反序列化为正确的类型时,YAML将知道collection:
的值将是没有显式标记的数据点列表。但是,我们有一个开销,因为我们每次都指定字段名称time
和data
。所以,让我们试着摆脱它们:
name: My Name
computer_name: My Computer
collection:
- [ 1:30, foo ]
- [ 2:20, bar ]
大多数YAML框架将提供将这些YAML序列反序列化为适当数据类的必要功能。我们仍然在YAML语法中。现在,让我们看看我们是否可以在那里获得实际的CSV:
name: My Name
computer_name: My Computer
collection: |
1:30;foo
2:20;bar
使用YAML文字块标量,我们现在将集合数据输入为标量,然后我们可以使用CSV解析器进行解析。我们甚至可以在遇到collection:
的值时指示我们的YAML实现立即执行此操作。
使用JSON作为主序列化格式来执行此操作会更加困难,因为JSON没有配备块标量。 XML也可以工作,但它本身非常臃肿。
虽然我们在YAML,但还有另一种可能的解决方案:使用文档结束标记向YAML解析器发出YAML文档在此处结束的信号,并将CSV数据放在其后面。类似的事情在Jekyll中完成,以将“YAML前面的事物”与内容分开。它看起来像这样:
name: My Name
computer_name: My Computer
...
1:30;foo
2:20;bar
...
是文档结束标记。 Jekyll使用---
代替,根据规范将在那里开始第二个YAML文档,我不知道为什么他们选择这样做。 ...
是更符合规范的方式。
答案 1 :(得分:1)
看到这一点。
使用XmlAttribute
创建一些模型:
public class Foo
{
[XmlAttribute]
public string Bar { get; set; }
[XmlAttribute]
public List<int> List1 { get; set; }
[XmlAttribute]
public List<double> List2 { get; set; }
}
序列化:
var foo = new Foo
{
Bar = "test",
List1 = new List<int> { 1, 2, 3 },
List2 = new List<double> { 0.1, 0.2, 0.3 }
};
var xs = new XmlSerializer(typeof(Foo));
var settings = new XmlWriterSettings { NewLineOnAttributes = true, Indent = true };
using (var xmlWriter = XmlWriter.Create(Console.Out, settings))
{
xs.Serialize(xmlWriter, foo);
}
Console.WriteLine();
结果紧凑且易读:
<Foo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
Bar="test"
List1="1 2 3"
List2="0.1 0.2 0.3" />
不要重新发明轮子。
答案 2 :(得分:0)
我找到了两个折衷的解决方案,它们很好用。
<GUID>.csv
<GUID>.xml
<GUID.yaml>
<GUID>.json
因此,flyx的答案已被接受为答案。非常感谢!