Metzger
Metzger

Reputation: 103

C# getting specific elements from XML

How can I get specified elements from this XML file? Let's say I only want the sub11, sub12, etc parts in the end of the tag that might contain SUB**, nothing or something else from each tag into an array?

Also, how could I get the Ex Name with each tag even while there are two Tags under one Ex? If I'm writing a row to list i would want Ex name then all tag info after that. Like for first row example: test1, Subject1, SUB11, 80, SUB12, 31, SUB13, 2 example output of the first EX in to list row. Second one should be like: test2, Subject2, SUB21, 100, SUB22, 20, SUB23, 0 Third one: test2, Subject3, SUB31, etc...

I have real experience with getting data from xml files. So I have no idea how to target spesific parts, even thou searching for hours on how to target xml nodes, child nodes, etc etc did not find what I wanted.

<Folder>
   <Ex>
      <Name>test1</Name>
      <Tags>
         <TagEx>
            <Name>Subject1</Name>
            <Tag Type="Maximum" Score="80" ExxTag="no">SUB11</Tag>
            <Tag Type="Average" Perc="31" ExxTag="no">SUB12</Tag>
            <Tag Type="Status" Results="2" ExxTag="no">SUB13</Tag>
         </TagEx>
      </Tags>
   </Ex>
   <Ex>
      <Name>test2</Name>
      <Tags>
         <TagEx>
            <Name>Subject2</Name>
            <Tag Type="Maximum" Score="100" ExxTag="no">SUB21</Tag>
            <Tag Type="Average" Perc="20" ExxTag="no">SUB22</Tag>
            <Tag Type="Status" Results="0" ExxTag="no">SUB23</Tag>
         </TagEx>
      </Tags>
      <Tags>
         <TagEx>
            <Name>Subject3</Name>
            <Tag Type="Maximum" Score="10" ExxTag="no">SUB31</Tag>
            <Tag Type="Average" Perc="50" ExxTag="no">SUB32</Tag>
            <Tag Type="Status" Results="3" ExxTag="no">SUB33</Tag>
         </TagEx>
      </Tags>
   </Ex>
</Folder>

I have tried a few ways but I end up getting empty values something totally different.

EDIT: As requested i can provide what I tried but it does not help in this case as its mostly irrelevant as I want targeting of certain not all as I do it now but here it goes:

        var xmldoc = XDocument.Load(ExFile);

        foreach (var name in xmldoc.Descendants("TagEx").Elements()
                            .Select(x => new {
                                Value = x.Value,
                                Type = x.Attribute("Type"),
                                Score = x.Attribute("Score"),
                                Perc = x.Attribute("Perc"),
                                Rest = x.Attribute("Results"),
                                ExxTag = x.Attribute("ExxTag")
                            }))

    {

        if (name.Score != null)
        {
            DScore = name.Score.ToString();
    AScore.Add(ClearSTR(DScore));
        }
    for (int i = 0; i < AType1.Count; i++)
        {
        string[] row = { etc[i],AScore[i],etc[i],etc[i],etc[i],etc[i]};
        var listViewItem = new ListViewItem(row);
        ListViewData.Items.Add(listViewItem);
        }

EDIT2: I solved it by just collecting all of the xml data instead of picking what I want and then sorting them with loops by order of receiving items and by possibilities in what the values may hold. It works perfectly, but its not what I wanted. I just wanted to target pick what i want. So I wont add this as solution as I would still love to know how to target pick things from xml.

Thanks for any help!

Upvotes: 1

Views: 73

Answers (1)

Enigmativity
Enigmativity

Reputation: 117064

Give this a go:

IEnumerable<IEnumerable<string>> data =
    from ex in XDocument.Parse(source).Root.Elements("Ex")
    let exname = ex.Element("Name").Value
    from tags in ex.Elements("Tags")
    let tagex = tags.Element("TagEx")
    let tagexname = tagex.Element("Name").Value
    let maximum =
        from tag in tagex.Elements("Tag")
        where tag.Attribute("Type").Value == "Maximum"
        select new [] { tag.Value, tag.Attribute("Score").Value }
    let average =
        from tag in tagex.Elements("Tag")
        where tag.Attribute("Type").Value == "Average"
        select new [] { tag.Value, tag.Attribute("Perc").Value }
    let status =
        from tag in tagex.Elements("Tag")
        where tag.Attribute("Type").Value == "Status"
        select new [] { tag.Value, tag.Attribute("Results").Value }
    let xs = maximum.Concat(average).Concat(status).SelectMany(x => x)
    select new [] { exname, tagexname, }.Concat(xs);

I get:

test1, Subject1, SUB11, 80, SUB12, 31, SUB13, 2
test2, Subject2, SUB21, 100, SUB22, 20, SUB23, 0
test2, Subject3, SUB31, 10, SUB32, 50, SUB33, 3

Upvotes: 1

Related Questions