c # Разобрать XML и сохранить узлы в сетке - PullRequest
0 голосов
/ 08 мая 2018

Это 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    |
             ......

EDIT

Оба решения, к сожалению, не сработали ... В случае, если это поможет, вот пример xml, над которым я работаю: ссылка

Ответы [ 2 ]

0 голосов
/ 08 мая 2018

Если это не удастся, у вас может быть больше одного 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());
0 голосов
/ 08 мая 2018

Исходя из обсуждения в комментариях, этот код будет анализировать элементы 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") 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...