使用 C#/Linq 将 XML 平展到 DataGridView
本文关键字:DataGridView XML Linq 使用 | 更新日期: 2023-09-27 17:57:18
有很多
这样的问题,但我可以向你保证,这个问题非常独特!我需要一个通用解决方案将 XML 数据平展为两列网格(字段、值),但真正的挑战是每个响应的 XML 数据的层次结构都不同!
这是以XML格式存储在数据库中的审计数据,我无法更改这些响应的结构,但需要处理任何可能的层次结构,并在简单的网格中向用户显示结果。
下面是 XML 结构的示例:
<xml>
<results>
<resultsDTO>
<reportid>173601</reportid>
<results>
<displayName>Item 1</displayName>
<someParameter>blahblah</someParameter>
<hidden>false</hidden>
<values>
<value>10</value>
<resultType>PERCENTAGE</resultType>
</values>
<values>
<value>some.pdf</value>
<resultType>PDF</resultType>
</values>
<values>
<value>Findings of Item 1</value>
<resultType>FINDINGS</resultType>
</values>
</results>
<results>
<displayName>Item 2</displayName>
<someParameter>blahblah</someParameter>
<hidden>false</hidden>
<values>
<value>20</value>
<resultType>PERCENTAGE</resultType>
</values>
<values>
<value/>
<resultType>PDF</resultType>
</values>
<values>
<value>Findings of Item 2</value>
<resultType>FINDINGS</resultType>
</values>
</results>
<reportTexts>
<value/>
<resultType>HISTORY</resultType>
</reportTexts>
<reportTexts>
<value>Some info here.</value>
<resultType>INFORMATION</resultType>
</reportTexts>
</resultsDTO>
</results>
</xml>
正如您从 XML 中看到的那样,在同一级别上总是有一个"resultType"和"value",但是我需要一种方法来遍历此 XML,而无需定义任何硬编码路径(XML/Results/ResultsDTO/Results/Values/),这些路径将在任何级别找到这些 resultType 和值,并且还处理一些特殊的数据规则。
我正在尝试将这些值放入 GridView 输出中,如下所示:
[Field], [Value]
Item 1 - Percentage, 10
Item 1 - Findings, Findings of Item 1
Item 2 - Percentage, 20
Item 2 - Findings, Findings of Item 2
History, NULL
Information, Some info here.
这是我当前的代码,它显示了我想要实现的目标的一半:
XDocument doc = XDocument.Load(@"XMLFile1.xml");
var query = from c in doc.Descendants("xml").Elements("results").Elements("resultsDTO").Elements("results").Elements("values").Where(n => n.Element("resultType").Value != "PDF")
select new
{
Field = c.Parent.Element("displayName") == null ? c.Element("resultType").Value : c.Parent.Element("displayName").Value + " - " + c.Element("resultType").Value,
Value = c.Element("value").Value
};
dataGridView1.DataSource = query.ToList();
我正在禁止显示"PDF"结果类型,并将显示名称附加到结果类型(如果它存在于父节点中!),因为它不适用于其他节点。
这目前只获取XML/Results/ResultsDTO/Results/Values/下的值,而不是XML/Results/ResultsDTO/ReportTexts中的值。
任何帮助将不胜感激!谢谢。
你在大多数情况下是对的。您需要做的就是:
- 也联合了报告文本元素的后代。
- 后代不需要你遍历路径。 您可以提供任何起始路径。
使用以下查询:
var query = from c in doc.Descendants("values").Union(doc.Descendants("reportTexts")).Where(n => n.Element("resultType").Value != "PDF")
select new
{
Field = c.Parent.Element("displayName") == null ? c.Element("resultType").Value : c.Parent.Element("displayName").Value + " - " + c.Element("resultType").Value,
Value = c.Element("value").Value // you can replace "" by null here
};
输出如下:
[Field], [Value]
Item 1 - Percentage, 10
Item 1 - Findings, Findings of Item 1
Item 2 - Percentage, 20
Item 2 - Findings, Findings of Item 2
History, ""
Information, Some info here.