简体   繁体   中英

Using attributes to find value linq

I'm a LINQ beginner and need some help. Below is the important part of the generated XML generated by a rest query.

<FormData FormOID="F_TABLEOFMODAL_V20" OpenClinica:Version="v2.0" OpenClinica:Status="initial data entry">
    <ItemGroupData ItemGroupOID="IG_TABLE_MODALITYTABLE" ItemGroupRepeatKey="3" TransactionType="Insert">
        <ItemData ItemOID="I_TABLE_MODAL_DATE_TABLE" Value="2014-04-10" />
        <ItemData ItemOID="I_TABLE_MODAL_TYPE_TABLE" Value="4" />
    </ItemGroupData>
    <ItemGroupData ItemGroupOID="IG_TABLE_MODALITYTABLE" ItemGroupRepeatKey="1" TransactionType="Insert">
        <ItemData ItemOID="I_TABLE_MODAL_DATE_TABLE" Value="2014-04-01" />
        <ItemData ItemOID="I_TABLE_MODAL_TYPE_TABLE" Value="2" />
    </ItemGroupData>
    <ItemGroupData ItemGroupOID="IG_TABLE_MODALITYTABLE" ItemGroupRepeatKey="2" TransactionType="Insert">
        <ItemData ItemOID="I_TABLE_MODAL_DATE_TABLE" Value="2014-04-04" />
        <ItemData ItemOID="I_TABLE_MODAL_TYPE_TABLE" Value="1" />
    </ItemGroupData>
</FormData>

What i want to get to are the ItemOIDs. My question is is there some way to get Values for all ItemOID="I_TABLE_MODAL_DATE_TABLE"(ans: two dates) and ItemOID="I_TABLE_MODAL_TYPE_TABLE" (ans: two numbers). The code below works but this uses ItemData for the first element (called date) and then skipping one to second element (type).

////Print out xml to use?
                    var doc = XDocument.Load(XmlReader.Create(streaming));

                    XNamespace nsSys = "http://www.cdisc.org/ns/odm/v1.3";

                    //loop through <ItemGroupData> to get both date and type value
                    //from each iteration
                    var items = from i in doc.Descendants(nsSys + "ItemGroupData")
                                select new
                            {
                                date = (string)i.Element(nsSys + "ItemData").Attribute("Value"),
                                type = (string)i.Descendants(nsSys + "ItemData").Skip(1).First().Attribute("Value")
                            };
                    //Catch here?

                    DataTable modDt = new DataTable();
                    modDt.Columns.Add(new DataColumn("Date", typeof(string)));
                    modDt.Columns.Add(new DataColumn("Type", typeof(string))); //changed to string?

                    //add LINQ-to-XML query result to DataTable

                    foreach (var item in items)
                    {
                        //convert item.date string to DateTime  
                        //then convert it back to string with different format
                        modDt.Rows.Add(DateTime.ParseExact(item.date, "yyyy-MM-dd", CultureInfo.InvariantCulture)
                                       .ToString("MM/dd/yy"),
                                       int.Parse(item.type));
                    }

                    //Value of OC output
                    //1=mr,2=ct,3=pet,4=us,5=meg,6=ecg (put if statements before xnat rest ssh string)
                    for (int i = 0; i <= modDt.Rows.Count - 1; i++)
                    {
                        modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("1", "mr");
                        modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("2", "ct");
                        modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("3", "pet");
                        modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("4", "us");
                        modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("5", "meg");
                        modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("6", "ecg");
                    }

I've started writting some code shown below. The adding of data into datatable still does not work sorry. However the idea of what i'm trying to do is in there.

            DataTable modDt = new DataTable();
            modDt.Columns.Add(new DataColumn("Date", typeof(string)));
            modDt.Columns.Add(new DataColumn("Type", typeof(string))); //changed to string?

            var document = XDocument.Load("doc.xml"); 

            XNamespace nsSys = "http://www.cdisc.org/ns/odm/v1.3";

            //Get nodes separated by inner child element

            var itd = document.Descendants(nsSys + "ItemData")
               .Where(t => (string)t.Attribute("ItemOID") == "I_TABLE_MODAL_DATE_TABLE");

            var itds = itd.Attributes("Value").ToArray();

            foreach (var it in itds)
            {
                var subA = it.ToString();
                var subAA = subA.ToCharArray();
                var subB = subAA.Skip(9).Take(8).ToArray();

                string sub = new string(subB);
                var subBB = sub.Split('-').ToArray();
                string subC = subBB[1] + "/" + subBB[2] + "/" + subBB[0];
                foreach (DataRow dr in modDt.Rows)
                {
                    dr["Date"] = subC;  
                }

                Console.WriteLine(subC);                
            }

            var itt = document.Descendants(nsSys + "ItemData")
               .Where(t => (string)t.Attribute("ItemOID") == "I_TABLE_MODAL_TYPE_TABLE");

            var itty = itt.Attributes("Value").ToArray();

            foreach (var et in itty)
            {
                var subz = et.ToString();
                var subzz = subz.ToCharArray();
                var subx = subzz.Skip(7).Take(1).ToArray();
                string subxx = new string(subx);

                foreach (DataRow dt in modDt.Rows)
                {
                    dt["Type"] = subxx;
                }

                Console.WriteLine(subxx);
            }

            //for (int i = 0; i <= modDt.Rows.Count - 1; i++)
            //{
            //    modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("1", "mr");
            //    modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("2", "ct");
            //    modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("3", "pet");
            //    modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("4", "us");
            //    modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("5", "meg");
            //    modDt.Rows[i][1] = modDt.Rows[i][1].ToString().Replace("6", "ecg");
            //}

            foreach (DataRow row in modDt.Rows) // Loop over the rows.
            {
                string sessionDate = row["Date"].ToString();
                string mod = row["Type"].ToString();
                string drow = "aa" + sessionDate + "bb" + mod + "cc"; 
                Console.WriteLine(drow);
            }

            Console.Read();

Thank you so much for your help and your time. It is greatly appreciated. Cheers.

Current Attempt

            DataTable modDt = new DataTable();
            modDt.Columns.Add(new DataColumn("Date", typeof(string)));
            modDt.Columns.Add(new DataColumn("Type", typeof(string))); //changed to string?

            var document = XDocument.Load("doc.xml"); 

            XNamespace nsSys = "http://www.cdisc.org/ns/odm/v1.3";

            //Get nodes separated by inner child element
            var values = document.Descendants(nsSys + "ItemData")
           .Where(t => t.Attribute("ItemOID").Value == "I_TABLE_MODAL_DATE_TABLE")
           .Select(x => x.Attribute("Value").Value);

            foreach (var item in values)
            {
                modDt.Rows.Add(DateTime.ParseExact(item, "yyyy-MM-dd", CultureInfo.InvariantCulture).ToString("MM/dd/yy"),null);
            }


            var typevalues = document.Descendants(nsSys + "ItemData")
            .Where(t => t.Attribute("ItemOID").Value == "I_TABLE_MODAL_TYPE_TABLE")
            .Select(x => x.Attribute("Value").Value);

            foreach (var item in typevalues)
            {
                modDt.Rows.Add(null ,int.Parse(item));
            }

            foreach (DataRow row in modDt.Rows)
            {
                string sessionDate = row["Date"].ToString();
                string mod = row["Type"].ToString();

                string xnatCli = mod + sessionDate;
                Console.Write(xnatCli);


            }

i am trying to answer your question in a single line of code

var values = document.Descendants("ItemData")
           .Where(t => t.Attribute("ItemOID").Value == "I_TABLE_MODAL_DATE_TABLE")
           .Select(x => x.Attribute("Value").Value)

after this line the values collection will have all the dates. same can be applied to other queries as well.

Update: the solution below use linq to sql, assuming class FormDataContext is prepared for connecting database to relevant table.

FormDataContext db = new FormDataContext();

[Table(Name = "FormData")]
public class FormData
{
        [Column]
        public DateTime Date;
        [Column]
        public int Type;
}

IEnumerable<FormData> values = document.Descendants("ItemGroupData").Select(t => { 
    return new FormData {
        FormDate = Convert.ToDateTime(t.XPathSelectElement("ItemData[@ItemOID='I_TABLE_MODAL_DATE_TABLE']").Attribute("Value").Value),
        Type = Convert.ToInt32(t.XPathSelectElement("ItemData[@ItemOID='I_TABLE_MODAL_TYPE_TABLE']").Attribute("Value").Value)
    }; 
});


foreach (FormData data in values) {
    db.Form.InsertOnSubmit(data);
}

db.SubmitChanges();

This is just an example to store the required two fields to db. You may adjust the example based on your needs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM