0
votes
<?xml version="1.0" encoding="ISO-8859-1"?>
<detail id="TestXML">
  <styles>
    <Maininfo id="Set1">
      <info1>Test1</info1>
      <info2>Test2</info2>
      <info2>Test3</info2>
      <secondinfo>
        <secondinfo-base id="1234567">
          <description>BlahBlah</description>
          <quantity>1</quantity>
        </secondinfo-base>
      </secondinfo>
      <colors>
        <color id="54321">
          <color-id>54321</color-id>
          <name>Test Color</name>
        </color>
      </colors>
    </Maininfo>
    </styles>
    <styles>
    <Maininfo id="Set2">
      <info1>Test4</info1>
      <info2>Test5</info2>
      <info2>Test6</info2>
      <secondinfo>
        <secondinfo-base id="7654321">
          <description>BlahBlahandBlah</description>
          <quantity>2</quantity>
        </secondinfo-base>
      </secondinfo>
      <colors>
        <color id="12345">
          <color-id>12345</color-id>
          <name>Yellow</name>
        </color>
        <color id="23456">
          <color-id>23456</color-id>
          <name>Green</name>
        </color>
        <color id="34567">
          <color-id>34567</color-id>
          <name>Red</name>
        </color>
      </colors>
    </Maininfo>
    </styles>   
</detail>

I'm trying to build a file that has each of the color ids and names grouped together with the info1, info2, info3 fields. For example, I need to manage to come up with 4 different groups with this information.

  • Group 1 = Set 1, Test1, Test2, Test3, 1234567, 54321, Test Color
  • Group 2 = Set 2, Test4, Test5, Test6, 7654321, 12345, Yellow
  • Group 3 = Set 2, Test4, Test5, Test6, 7654321, 23456, Green
  • Group 4 = Set 2, Test4, Test5, Test6, 7654321, 34567, Red

I can get the colors and everything, but I cant seem to get the information preceding it.

This is what I was doing to get the colors and color id.

        var xml = Xdocument.Load("test.xml");
        var color = from c in xml.Root.Descendants("color")
                            select new{
                            colorNumber = (string)c.Element("color-id"),
                            colorName = (string)c.Element("name"),
                            };

I've tried so many different ways to getting the information that would pair with it, but I just can't figure it out. I hope I explained this well enough.

I have looked around quite a bit on this site for something similar to what I'm asking, but I can't find anything. Can someone please help?

It was hard thinking of a subject for this problem. Sorry if it was misleading.

Thanks

1

1 Answers

0
votes

If I understood what you need correctly, something like this should work for your example. You can use the Parent property of the color elements you find to go traverse back up the tree and pair it with the other information you want.

var colorGroups = xml
    .Descendants("color")
    .Select(colorElement => 
    {
        XElement mainInfo = colorElement.Parent.Parent;

        return new
        {
            Set = mainInfo.Attribute("id").Value,
            Color = colorElement.Element("name").Value,
            Id = colorElement.Element("color-id").Value,
            SecondInfo = mainInfo.Element("secondinfo").Elements("secondinfo-base").Select(b => b.Attribute("id").Value).ToList(),
            Infos = mainInfo.Elements().Where(b => b.Name.LocalName.StartsWith("info")).Select(b => b.Value).ToList()
        };
    });

This produces an enumerable of dynamically typed objects. To access this information you could do, for example,

foreach (var colorGroup in colorGroups)
{
    Console.WriteLine(colorGroup.Set);
}

As they're dynamically typed, you won't have intelli-sense for the property names in Visual Studio, but it'll still compile and work at runtime. I returned dynamic objects to follow your original code, but you can use a real class here instead (personally I would prefer this, infact I might be tempted to deserialize the whole lot into a set of objects since it seems you're using most of the information anyway and it'd be easier to work with and more readable, but it's more than I want to get into here).