使用 C# 解析 XML 文件
Posted
技术标签:
【中文标题】使用 C# 解析 XML 文件【英文标题】:Parse XML file using C# 【发布时间】:2021-03-27 18:08:32 【问题描述】:我是 XML 新手。我需要解析这个 XML 并从 -Field- 元素和 -name- 属性中读取值。
我需要来自 accountID、deviceID、odometerKM 的值
这是 XML:
<GTSResponse command="dbget" result="success">
<Record table="EventDataView" partial="true">
<Field name="accountID" primaryKey="true" alternateKeys="adtkey,driverkey">
<![CDATA[salesdemo]]>
</Field>
<Field name="deviceID" primaryKey="true" alternateKeys="adtkey">
<![CDATA[bubba_polaris]]>
</Field>
<Field name="timestamp" primaryKey="true" alternateKeys="adtkey,driverkey">1605919705</Field>
<Field name="statusCode" primaryKey="true">0xF010</Field>
<Field name="latitude">0.0</Field>
<Field name="longitude">0.0</Field>
<Field name="odometerKM">0.2566422</Field>
<Field name="odometerOffsetKM">0.0</Field>
</Record>
<Record table="EventDataView" partial="true">
<Field name="accountID" primaryKey="true" alternateKeys="adtkey,driverkey">
<![CDATA[salesdemo]]>
</Field>
<Field name="deviceID" primaryKey="true" alternateKeys="adtkey">
<![CDATA[bubba_polaris]]>
</Field>
<Field name="timestamp" primaryKey="true" alternateKeys="adtkey,driverkey">1605919705</Field>
<Field name="statusCode" primaryKey="true">0xF010</Field>
<Field name="latitude">0.0</Field>
<Field name="longitude">0.0</Field>
<Field name="odometerKM">0.23445323</Field>
<Field name="odometerOffsetKM">0.0</Field>
</Record>
</GTSResponse>
这是我尝试过的代码:
XDocument doc = XDocument.Parse(receivedResponse);
Dictionary<string, string> dataDictionary = new Dictionary<string, string>();
foreach (XElement element in doc.Descendants().Where(p => p.HasElements == false))
int keyInt = 0;
string keyName = element.Name.LocalName;
while (dataDictionary.ContainsKey(keyName))
keyName = element.Name.Namespace.ToString();
keyName = element.Name.LocalName + "_" + keyInt++;
dataDictionary.Add(keyName, element.Value);
foreach (var x in dataDictionary)
Console.WriteLine("keyName: " + x.Key + " value: " + x.Value);
当我运行它时,它会遍历所有 -Field- 元素,但它不使用 -name-。我需要查看 -name- 以便我知道我有什么价值。我将更新我的数据库,并需要按名称相应地循环和更新字段。
【问题讨论】:
您需要将元素替换为后代 From : .Elements("Field") To : .Descendants("Field") 谢谢 jdweng - 我会试试的。 你想在 while 循环中做什么?如果要更改值 dataDictionary[keyName] = "new value"; 我正在遍历 XML 文件中的所有元素。我发布的 XML 仅用于一个记录。但是实际数据中有多个 Record 元素...我不明白您评论要更改的内容..... 【参考方案1】:有一个 Record
元素您没有浏览过。
试试这个:
var values =
doc
.Root
.Elements("Record")
.SelectMany((x, n) => x.Elements("Field").Select(y => new field = y, index = n ))
.ToDictionary(
x => $"(string)x.field.Attribute("name")_x.index",
x => (string)x.field);
我从你的样本数据中得到这个:
我认为你最好这样做:
Dictionary<int, Dictionary<string, string>> values =
doc
.Root
.Elements("Record")
.Select((x, n) => (x, n))
.ToDictionary(
y => y.n,
y => y.x
.Elements("Field")
.ToDictionary(
z => (string)z.Attribute("name"),
z => (string)z));
然后你得到:
【讨论】:
嗨 Enigmativity - 感谢您的帮助 - 现在出现错误:System.ArgumentException: 'An item with the same key has been added.' @Tdigges - 那是因为有多个Record
元素。听起来您需要Dictionary<string, Dictionary<string, string>>
。对吗?
是的,我发现这也是正确的。我找到了遍历 Dictionary 尝试以下:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
class Program
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
string receivedResponse = File.ReadAllText(FILENAME);
XDocument doc = XDocument.Parse(receivedResponse);
Dictionary<string, Dictionary<string, List<Field>>> dataDictionary = doc.Descendants("Record")
.GroupBy(x => (string)x.Attribute("table"), y => y)
.ToDictionary(x => x.Key, y => y.Elements("Field")
.GroupBy(a => (string)a.Attribute("name"), b => new Field(b))
.ToDictionary(a => a.Key, b => b.ToList()));
public class Field
public string name get; set;
public Boolean? primaryKey get; set;
public string alternateKeys get; set;
public string text get; set;
public Field(XElement field)
name = (string)field.Attribute("Field");
primaryKey = (field.Attribute("primaryKey") == null) ? null : (Boolean?)field.Attribute("primaryKey");
alternateKeys = (field.Attribute("alternateKeys") == null) ? null : (string)field.Attribute("alternateKeys");
text = (string)field;
【讨论】:
太棒了!这对我有很大帮助……我做了一些更改以获取要填充的值………… public Field(XElement field) name = (string)field.Attribute("name"); primaryKey = (field.Attribute("primaryKey") == null) ? null : (Boolean?)field.Attribute("primaryKey"); alterKeys = (field.Attribute("alternateKeys") == null) ? null : (string)field.Attribute("alternateKeys");文本=字段。值;以上是关于使用 C# 解析 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章