代码之家  ›  专栏  ›  技术社区  ›  aggicd

c#解析XML并将节点存储到网格

  •  0
  • aggicd  · 技术社区  · 7 年前

    这是 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示例: link

    2 回复  |  直到 7 年前
        1
  •  1
  •   DavidG    7 年前

    根据注释中的讨论,此代码将解析 ItemData 元素,但将丢失它们是否来自 Mdid Zdid 第节:

    首先是保存项目数据的类:

    public class ItemData
    {
        public string ItemID { get; set; }
        public string IsNull { get; set; }
        public string Value { get; set; }
    }
    

    以及处理XML的Linq:

    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") 
    
        2
  •  0
  •   jdweng    7 年前

    如果失败,则可能会有多个具有相同值的one 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());