[英]c# Parse XML and store nodes to grid
这是我从请求中获得的XML
:
<ODM xmlns:.....>
<Data DID="Mdid">
<SubjectData SubjectKey="1">
<SRef Location="Loc1"/>
<SEventData SEventID="SID1">
<FormData FormID="FID1">
<ItemGroupData ItemGroupID="IGID1">
<ItemData ItemID="IID1" IsNull="Yes"/>
<ItemData ItemID="IID2" IsNull="Yes"/>
<ItemData ItemID="IID3" IsNull="Yes"/>
<ItemData ItemID="IID4" Value="cvs"/>
</ItemGroupData>
</FormData>
</SEventData>
</SubjectData>
</Data>
<Data DID="Zdid">
<SubjectData SubjectKey="2">
<SRef Location="Loc2"/>
<SEventData SEventID="SID2">
<FormData FormID="FID2">
<ItemGroupData ItemGroupID="IGID2">
<ItemData ItemID="IID11" Value="xcs"/>
<ItemData ItemID="IID12" IsNull="Yes"/>
<ItemData ItemID="IID13" IsNull="Yes"/>
<ItemData ItemID="IID14" Value="zfv"/>
</ItemGroupData>
</FormData>
</SEventData>
</SubjectData>
</Data>
........
</ODM>
如何从特定的Data
, SubjectData
, SEventData
, FormData
, ItemGroupData
或ItemData
将项目及其值存储在网格中?
这是我为ItemData
尝试过的方法,但它返回null
:
var xdoc = XDocument.Parse(response.RawXMLString());
var items = xdoc.Descendants("ItemData")
.ToDictionary(i => (string)i.Attribute("ItemID"),
i => (string)i.Attribute("Value"));
例
“ Mdid”数据项(对于SubjectKey
== 1, SEventID
=“ SID1”等将是相同的。但是“ Zdid”数据项将有所不同,因为它可能包含不同的ItemData
):
ItemID | IsNull | Value
IID1 | Yes |
IID2 | Yes |
......
编辑
不幸的是,这两个解决方案都无法正常工作……如果有帮助,这里是我正在处理的示例XML: 链接
基于注释中的讨论,此代码将把ItemData
元素解析为一个列表,但是将丢失有关它们来自Mdid
还是Zdid
部分的上下文:
首先是一个保存项目数据的类:
public class ItemData
{
public string ItemID { get; set; }
public string IsNull { get; set; }
public string Value { get; set; }
}
和Linq处理XML:
var items = xdoc
.Descendants("Data")
.Where(d => d.Attribute("DID").Value == "Mdid") //These lines can be added
.Descendants("ItemData") //to filter if you need them
.Select(i => new ItemData
{
ItemID = (string)i.Attribute("ItemID"),
IsNull = (string)i.Attribute("IsNull"),
Value = (string)i.Attribute("Value")
});
如果需要包括名称空间,请按照以下步骤操作:
XNamespace ns = "http://www.cdisc.org/ns/odm/v1.3";
然后在名称前加上`ns。 例如:
.Descendants(ns+"ItemData")
如果失败,则可能会有多个具有相同值的ItemData。 尝试以下操作:
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string, string> items = doc.Descendants().Where(x => x.Name.LocalName == "ItemData")
.GroupBy(x => (string)x.Attribute("ItemOID"), y => y.Attribute("IsNull") != null ? "Null" : (string)y.Attribute("Value"))
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
//if above fails tgry following
Dictionary<string, List<string>> items2 = doc.Descendants().Where(x => x.Name.LocalName == "ItemData")
.GroupBy(x => (string)x.Attribute("ItemOID"), y => y.Attribute("IsNull") != null ? "Null" : (string)y.Attribute("Value"))
.ToDictionary(x => x.Key, y => y.ToList());
//or use two level dictionary
Dictionary<int, Dictionary<string, string>> items3 = doc.Descendants().Where(x => x.Name.LocalName == "SubjectData")
.GroupBy(x => (int)x.Attribute("SubjectKey"), y => y.Descendants().Where(z => z.Name.LocalName == "ItemData")
.GroupBy(a => (string)a.Attribute("ItemOID"), b => b.Attribute("IsNull") != null ? "Null" : (string)b.Attribute("Value"))
.ToDictionary(a => a.Key, b => b.FirstOrDefault()))
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.