命名控件需要
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Xml;
using System.Linq;
XML转Json/JObject 用到的全部核心API
核心转换静态方法JsonConvert.SerializexNode();
string jsonText=JsonConvert.SerializeXmlNode(xmlDoc);
//再把JSON字符串转换为JObject
JObject jobject=JObject.Parse(jsonText);
XmlDocument xmlDoc = new XmlDocument();
private void btn_xml_Click(object sender, EventArgs e)
{
xmlDoc.Load(@"./Config/Menu.xml");
string jsonText=JsonConvert.SerializeXmlNode(xmlDoc); //JsonConvert.SerializeXmlNode(xmlDoc)将繁琐的XML文档直接编程JSON格式的字符串
JObject jobj=JObject.Parse(jsonText); //JObject.Parse(jsonText)将JSON格式的字符串直接编程JObject对象
}
拿到 JObject / JToken / JArray 后,高频成员方法大全
层级关系:
JToken:抽象基类,JObject、JArray、JValue、JProperty 都继承它JObject:json 对象{ "a":1 },键值对集合JArray:json 数组[ {...}, {...} ]JValue:普通值(字符串、数字、bool)
🟢 JObject 常用
表格
| 用法 | 说明 |
|---|---|
jobj["keyName"] |
索引器,返回JToken;找不到返回 null,不抛异常 |
jobj.TryGetValue("key", out JToken token) |
安全获取,不会抛异常,推荐优先用 |
jobj.Property("keyName") |
获取属性对象JProperty,可以取 Name/Value |
jobj.Children() |
获取所有直接子节点,返回IEnumerable<JToken> |
jobj.Properties() |
获取全部属性集合IEnumerable<JProperty> |
jobj.ToObject<T>() |
反序列化为 C# 实体类,如jobj.ToObject<MenuConfig>() |
jobj.Remove("key") |
删除某个 key |
jobj.Add("key",value) |
新增属性 |
🟢 JToken(最常用,因为索引返回都是 JToken)
// 类型判断
token.Type == JTokenType.Array //是不是数组
token.Type == JTokenType.Object //是不是对象
token.Type == JTokenType.String
token is JArray arr; //模式匹配C#7+
token is JObject obj;
// 转换
string str = (string)token;
int num = (int)token;
// 递归子节点
token.Children();
token.Descendants(); //递归所有后代(深层全部子节点)
// 选择
token.SelectTokens("$..menuItem"); //jsonpath,递归找所有名为menuItem节点
cs
./Config/ProtDevicePara.xml
<dev>
<BaseData>
<DeviceConfigData>
<DeviceName>RS485COM</DeviceName>
<portName>COM3</portName>
<baudRate>115200</baudRate>
<dataBits>8</dataBits>
<parity>0</parity>
<stopBits>1</stopBits>
<sendMode>byte</sendMode>
</DeviceConfigData>
<DeviceConfigData>
<DeviceName>RS422COM测距1</DeviceName>
<portName>COM7</portName>
<baudRate>115200</baudRate>
<dataBits>8</dataBits>
<parity>0</parity>
<stopBits>1</stopBits>
<sendMode>string</sendMode>
</DeviceConfigData>
<DeviceConfigData>
<DeviceName>RS422COM测距2</DeviceName>
<portName>COM8</portName>
<baudRate>115200</baudRate>
<dataBits>8</dataBits>
<parity>0</parity>
<stopBits>1</stopBits>
<sendMode>string</sendMode>
</DeviceConfigData>
</BaseData>
<swRefreshDB>False</swRefreshDB>
</dev>
string fileName="./Config/ProtDevicePara.xml";
XmlDocumnet xmlDoc=new XmlDocument();
xmlDoc.Load(fileName);
string jsonText=JsonConvert.SerializeXmlNode(xmlDoc);
JObject jobj=JObject.Parse(jsonText);
JToken jToken=jobj["dev"]["BaseData"];
if(jToken.Type==JTokenType.Array){
JArray arr=(JArray)JToken;
MessageBox.Show("JToken jToken=jobj["dev"]["BaseData"]是数组");
foreach( var item in arr)
{
txt_ShowMessage.Text += item.ToString()+"\r\n";
}
}
else if (jToken.Type==JTokenType.Object)
{
JObject obj=(JObject)jToken;
txt_ShowMessage.Text += "jToken是单个Object类型\r\n";
}
//拿到dev BaseData 第二个DeviceConfigData中的sendMode
JToken itemToken=jobject["dev"]?["BaseData"]?["DeviceConfigData"]?[1];
if(itemToken.Type==JTokenType.Object){
string sendMode=(string itemToken["sendMode"];
textBox1.Text+=sendMode;
}
//拿到所有DeviceConfigData中的DeviceName:
JToken jToken2=jobject["dev"]["BaseData"]["DeviceConfigData"].Value<JArray>();
if (jToken2.Type==JTokenType.Array)
{
foreach (JToken item in jToken2)
{
textBox1.Text += item.ToString() + "\r\n"; //显示了所有的数据
}
}
string[] DeviceNames=jToken2.Select(data=>(string)data["DeviceName"]).ToArray();
string[] COMNames = jToken.Select(data => (string)data["portName"]).ToArray();