Question

I've got xml

<Customer>
  <Vendor Value="Vodafone">
    <CustomerBarcode>10010</CustomerBarcode>
    <Description>Vodafone CepLira 10 TL</Description>
    <UnitAmount>0</UnitAmount>
  </Vendor>
  <Vendor Value="Vodafone">
    <CustomerBarcode>10020</CustomerBarcode>
    <Description>Vodafone CepLira 20 TL</Description>
    <UnitAmount>0</UnitAmount>
  </Vendor>
  <Vendor Value="Vodafone">
    <CustomerBarcode>10030</CustomerBarcode>
    <Description>Vodafone CepLira 30 TL</Description>
    <UnitAmount>0</UnitAmount>
  </Vendor>
  <Vendor Value="Vodafone">
    <CustomerBarcode>10050</CustomerBarcode>
    <Description>Vodafone CepLira 50 TL</Description>
    <UnitAmount>0</UnitAmount>
  </Vendor>
  <Vendor Value="Vodafone">
    <CustomerBarcode>10100</CustomerBarcode>
    <Description>Vodafone CepLira 100 TL</Description>
    <UnitAmount>0</UnitAmount>
  </Vendor>
</Customer>
 var xml = new XElement("Customer",
                from prod in _customer
                group prod by new { prod.Vendor, prod.CustomerBarcode, prod.Description, prod.UnitAmount } into g
                select new XElement("Vendor",new XAttribute("Value",g.Key.Vendor),
                    new XElement("CustomerBarcode", g.Key.CustomerBarcode),
                     new XElement("Description", g.Key.Description),
                     new XElement("UnitAmount", g.Key.UnitAmount)
              ));

I want to group by Vendor Value like this:

  <Customer>
  <Vendor Value="Vodafone">
    <CustomerBarcode>10010</CustomerBarcode>
    <Description>Vodafone CepLira 10 TL</Description>
    <UnitAmount>0</UnitAmount>
    <CustomerBarcode>10020</CustomerBarcode>
    <Description>Vodafone CepLira 20 TL</Description>
    <UnitAmount>0</UnitAmount>
     <CustomerBarcode>10020</CustomerBarcode>
    <Description>Vodafone CepLira 20 TL</Description>
    <UnitAmount>0</UnitAmount>
     <CustomerBarcode>10030</CustomerBarcode>
    <Description>Vodafone CepLira 30 TL</Description>
    <UnitAmount>0</UnitAmount>
     <CustomerBarcode>10050</CustomerBarcode>
    <Description>Vodafone CepLira 50 TL</Description>
    <UnitAmount>0</UnitAmount>
     <CustomerBarcode>10100</CustomerBarcode>
    <Description>Vodafone CepLira 100 TL</Description>
    <UnitAmount>0</UnitAmount> 
  </Vendor>
</Customer>

How can I do this?

No correct solution

OTHER TIPS

You should define grouping key: in your case it would be Vender property value itself, not all properties.

And your should use SelectMany to get all group items into one big collection.

Following should do the trick:

var xml = new XElement("Customer",
                from prod in _customer
                group prod by prod.Vendor into g
                let vendor = g.Key
                let items = g.SelectMany(x => x)
                select
                    new XElement("Vendor",
                        new XAttribute("Value",g.Key.Vendor),
                        items.SelectMany(i => 
                            new XElement[] {
                                 new XElement("CustomerBarcode", i.CustomerBarcode),
                                 new XElement("Description", i.Description),
                                 new XElement("UnitAmount", i.UnitAmount)
                            }
                        )
                    )
                );

But, just to make it clear: I think that's XML structure is not really a good choice. You should group units together, probably use something like:

<Customer>
  <Vendor Value="Vodafone">
    <Unit>
      <CustomerBarcode>10010</CustomerBarcode>
      <Description>Vodafone CepLira 10 TL</Description>
      <UnitAmount>0</UnitAmount>
    </Unit>
    <Unit>
      <CustomerBarcode>10020</CustomerBarcode>
      <Description>Vodafone CepLira 20 TL</Description>
      <UnitAmount>0</UnitAmount>
    </Unit>
    <Unit>
      <CustomerBarcode>10020</CustomerBarcode>
      <Description>Vodafone CepLira 20 TL</Description>
      <UnitAmount>0</UnitAmount>
    </Unit>
    <Unit>
      <CustomerBarcode>10030</CustomerBarcode>
      <Description>Vodafone CepLira 30 TL</Description>
      <UnitAmount>0</UnitAmount>
    </Unit>
    <Unit>
      <CustomerBarcode>10050</CustomerBarcode>
      <Description>Vodafone CepLira 50 TL</Description>
      <UnitAmount>0</UnitAmount>
    </Unit>
    <Unit>
      <CustomerBarcode>10100</CustomerBarcode>
      <Description>Vodafone CepLira 100 TL</Description>
      <UnitAmount>0</UnitAmount>
    </Unit>
  </Vendor>
</Customer>

It makes the document much more readable. To achieve that, use following LINQ query:

var xml = new XElement("Customer",
                from prod in _customer
                group prod by prod.Vendor into g
                let vendor = g.Key
                let items = g.SelectMany(x => x)
                select
                    new XElement("Vendor",
                        new XAttribute("Value",g.Key.Vendor),
                        items.Select(i => 
                            new XElement("Unit",
                                 new XElement("CustomerBarcode", i.CustomerBarcode),
                                 new XElement("Description", i.Description),
                                 new XElement("UnitAmount", i.UnitAmount)
                            )
                        )
                    )
                );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top