如果要将JSON的一部分从一个流复制到另一个流,那么可以使用
JsonWriter.WriteToken(JsonReader)
Current = JToken.Load(jsonTextReader)
和
Encoding.ASCII.GetBytes(Current.ToString())
表示及其相关的内存开销:
using (var textWriter = new StreamWriter(destinationStream, new UTF8Encoding(false, true), 1024, true))
using (var jsonWriter = new JsonTextWriter(textWriter) { Formatting = Formatting.Indented, CloseOutput = false })
{
jsonWriter.WriteToken(jsonTextReader);
}
然而,Json.NET网站的
JsonTextReader
无法以相同的方式读取“chunks”中的单个字符串值
XmlReader.ReadValueChunk()
JsonWriter.WriteToken()
不会阻止这些字符串完全加载到内存中。
或者,您可以考虑
JsonReaderWriterFactory
. 这些读者和作者由
DataContractJsonSerializer
并实时地将JSON转换为XML
read
和
written
. 因为这些读者和作者的基类是
XmlReader
XmlWriter
做
支持分块读写字符串值。适当地使用它们将避免在大型对象堆中分配字符串。
为此,首先定义以下扩展方法,将JSON值的选定子集从输入流复制到输出流,如要流化的数据的路径所指定的那样:
public static class JsonExtensions
{
public static void StreamNested(Stream from, Stream to, string [] path)
{
var reversed = path.Reverse().ToArray();
using (var xr = JsonReaderWriterFactory.CreateJsonReader(from, XmlDictionaryReaderQuotas.Max))
{
foreach (var subReader in xr.ReadSubtrees(s => s.Select(n => n.LocalName).SequenceEqual(reversed)))
{
using (var xw = JsonReaderWriterFactory.CreateJsonWriter(to, Encoding.UTF8, false))
{
subReader.MoveToContent();
xw.WriteStartElement("root");
xw.WriteAttributes(subReader, true);
subReader.Read();
while (!subReader.EOF)
{
if (subReader.NodeType == XmlNodeType.Element && subReader.Depth == 1)
xw.WriteNode(subReader, true);
else
subReader.Read();
}
xw.WriteEndElement();
}
}
}
}
}
public static class XmlReaderExtensions
{
public static IEnumerable<XmlReader> ReadSubtrees(this XmlReader xmlReader, Predicate<Stack<XName>> filter)
{
Stack<XName> names = new Stack<XName>();
while (xmlReader.Read())
{
if (xmlReader.NodeType == XmlNodeType.Element)
{
names.Push(XName.Get(xmlReader.LocalName, xmlReader.NamespaceURI));
if (filter(names))
{
using (var subReader = xmlReader.ReadSubtree())
{
yield return subReader;
}
}
}
if ((xmlReader.NodeType == XmlNodeType.Element && xmlReader.IsEmptyElement)
|| xmlReader.NodeType == XmlNodeType.EndElement)
{
names.Pop();
}
}
}
}
现在,那个
string [] path
论证
StreamNested()
不
任何一种
jsonpath
XML阅读器
返回者
JsonReaderWriterFactory.CreateJsonReader()
反过来,用于此转换的映射由Microsoft在中记录
Mapping Between JSON and XML
value[*]
,所需的XML路径为
//root/value/item
. 因此,您可以通过执行以下操作来选择和流化所需的嵌套对象:
JsonExtensions.StreamNested(inputStream, destinationStream, new[] { "root", "value", "item" });
-
JSON和XML之间的映射
有点复杂。将一些示例JSON加载到
XDocument
使用以下扩展方法:
static XDocument ParseJsonAsXDocument(string json)
{
using (var xr = JsonReaderWriterFactory.CreateJsonReader(new MemoryStream(Encoding.UTF8.GetBytes(json)), Encoding.UTF8, XmlDictionaryReaderQuotas.Max, null))
{
return XDocument.Load(xr);
}
}
-
JObject.SelectToken Equivalent in .NET
.