提供一个获取一个JSON对象中获取对象的方法
Opened this issue · 2 comments
zenglei286 commented
现在很多 的接口都是JSON,提供一个根据JSON对象获取相应的数据。不是完整版的,不过提供一个思路。
using Hawk.Core.Connectors;
using Hawk.Core.Utils;
using Hawk.Core.Utils.Plugins;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Controls.WpfPropertyGrid.Attributes;
namespace Hawk.ETL.Plugins.Transformers
{
[XFrmWork("提取Json数据", "提取Json数据中的数据")]
public class GetJsonData : TransformerBase
{
[LocalizedDisplayName("提取模式")]
[LocalizedDescription("文档列表:[{}],转换为多个数据行构成的列表;单文档:{},将结果的键值对附加到本行;不进行转换:直接将值放入到新列")]
public ScriptWorkMode workMode { get; set; }
[LocalizedDisplayName("值路径")]
[LocalizedDescription("例如XX.yyy[0].jjjj")]
public string valuePath { get; set; }
public override bool Init(IEnumerable<IFreeDocument> docus)
{
IsMultiYield = workMode == ScriptWorkMode.List;
return base.Init(docus);
}
public override object TransformData(IFreeDocument datas)
{
var item = datas[Column];
if (item == null || string.IsNullOrWhiteSpace(item.ToString()))
return null;
dynamic d = null;
//try
//{
// d = serialier.DeserializeObject(item.ToString());
//}
//catch (Exception ex)
//{
// SetValue(datas, ex.Message);
// // XLogSys.Print.Error(ex);
// return null;
//}
//if (workMode == ScriptWorkMode.One)
//{
// var newdoc = ScriptHelper.ToDocument(d) as FreeDocument;
// newdoc.DictCopyTo(datas);
//}
//else
//{
// SetValue(datas, d);
//}
return null;
}
public override IEnumerable<IFreeDocument> TransformManyData(IEnumerable<IFreeDocument> datas)
{
if (string.IsNullOrWhiteSpace(valuePath))
{
foreach (var data in datas)
{
yield return data;
}
}
else
{
List<IFreeDocument> docs = new List<IFreeDocument>();
foreach (var data in datas)
{
var item = data[Column];
string[] pros = valuePath.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
object[] result = new object[1];
result[0] = (item);
for (int i = 0; i < pros.Length; i++)
{
result = GetValueFromJson(result, pros[i]).ToArray();
}
foreach (var d in result)
{
var doc = new FreeDocument();
doc.MergeQuery(data, NewColumn);
data.DictCopyTo(doc);
if (string.IsNullOrWhiteSpace(NewColumn))
{
doc.SetValue(Column, d);
}
else
{
doc.SetValue(NewColumn, d);
}
yield return doc;
}
}
}
}
Regex regex = new Regex(@"(?<pro>\w+)\[(?<index>\d+)\]");
public List<object> GetValueFromJson(object obj, string vp)
{
List<object> list = new List<object>();
if (obj.GetType().IsArray)
{
Array array = obj as Array;
if (regex.IsMatch(vp))
{
var match = regex.Match(vp);
int index = int.Parse(match.Groups["index"].Value);
string pro = match.Groups["pro"].Value;
if (array.Length <= index)
{
throw new Exception("数组长度不够!");
}
obj = array.GetValue(index);
list.AddRange(GetValueFromJson(obj, pro));
}
else
{
for (int i = 0; i < array.Length; i++)
{
var item = array.GetValue(i);
list.AddRange(GetValueFromJson(item, vp));
}
}
}
else
{
Dictionary<string, object> dict = obj as Dictionary<string, object>;
if (dict?[vp] == null)
{
return null;
}
else
{
list.Add(dict[vp]);
}
}
return list;
}
}
}
zenglei286 commented
这个是配合JsonTF来使用的
ferventdesert commented
感谢!