"Gambiarra" in C # with XML, I would like suggestions for improvement

6

I have this code without the "gambiarra", which returns the list with the values repeated:

var s = (from p in xmlDoc.Descendants("pais")
                           let Nomepais = p.Element("nome-pais").Value
                           let nomeconsulado = p.Element("consulados").Element("consulado").Element("nome-consulado").Value
                           let endereco = p.Element("consulados").Element("consulado").Element("endereco").Value
                           let cep = p.Element("consulados").Element("consulado").Element("cep").Value
                           from t in xmlDoc.Descendants("telefones")
                           let telefone = t.Elements("telefone").Select(f => f.Value).ToList()     
                           from e in xmlDoc.Descendants("emails")
                           let email = e.Elements("email").Select(m => m.Value).ToList()
                           where Nomepais == SSP.Consulado.pais
                           select new ListaConsulado.Consulado()
                           {             
                               NomePais = Nomepais,
                               Cep = "Cep: " + cep,
                               Endereco = endereco,
                               NomeConsulado = nomeconsulado,
                               Telefone = telefone,
                               Email = email
                           }
                           ).ToList();
lista.ItemsSource = s;

Before this screen, there are the countries:

Thatwhenyouselectone,yougotothelistofConsulates

And this, with the "gambiarra":

lista.ItemsSource = s.GroupBy(t => t.NomeConsulado).Select(g => g.First()).ToList();

Without"Gambiarra"

I wanted to know, if you have a way to improve this, why I think this is not the way to go. Suggestions?

ListaConsulado.cs

class ListaConsulado
    {

        public class Paises
        {
            public Paises()
            {
                this.NomePais = string.Empty;
                Consulados = new List<Consulado>();
            }
            public Paises(String NomePais)
            {
                this.NomePais = NomePais;
                Consulados = new List<Consulado>();
            }
            public Paises(String NomePais, List<Consulado> Consulados)
            {
                this.NomePais = NomePais;
                this.Consulados = Consulados;
            }

            public Paises(List<Consulado> Consulados)
            {
                this.NomePais = string.Empty;
                this.Consulados = Consulados;
            }
            public String NomePais { get; set; }
            public IList<Consulado> Consulados { get; set; }
        }

        public class Consulado
        {
            public string NomePais { get; set; }
            public string NomeConsulado { get; set; }
            public string Endereco { get; set; }
            public string Cep { get; set; }
            public string Fax { get; set; }
            public string Geral { get; set; }
            public string Honorario { get; set; }
            public string UrlSite { get; set; }
            public string NomeChefia { get; set; }
            public string Observacao { get; set; }
            public string Expediente { get; set; }
            public string Jurisdicao { get; set; }
            public List<string> Telefone { get; set; }
            public List<string> Email { get; set; }
            public BitmapImage NomeImgBandeira { get; set; }
        }
   }
}

XML:

<paises>

<pais>
        <nome-pais>Austrália</nome-pais>    
        <consulados>        
            <consulado>
                <nome-consulado>Consulado-Geral da Austrália em São Paulo - SP </nome-consulado>        
                <endereco>Alameda Santos, 700 - 9º andar conjunto 92, Cerqueira César, São Paulo-SP</endereco>      
                <cep>01418-100</cep>                
                <fax>(11) 3171-2889</fax>
                <geral>1</geral>
                <honorario>0</honorario>
                <nome_img_bandeira>flag_australia</nome_img_bandeira>
                <url-site></url-site>
                <emails></emails>
                <nome-chefia>Mark Argar</nome-chefia>
                <telefones>
                    <telefone>(11) 2112-6200</telefone>
                    <telefone>(11) 2112-6215 </telefone>
                    <telefone>(11) 3171-2851 </telefone>
                </telefones>
                <observacao>Auxílio a cidadãos australianos: (0xx11) 3171-2851</observacao>
                <expediente></expediente>
                <jurisdicao></jurisdicao>
            </consulado>
        </consulados>
    </pais>

<pais>
        <nome-pais>Áustria</nome-pais>
        <consulados>        
            <consulado>
                <nome-consulado>Consulado-Geral da Áustria em São Paulo - SP</nome-consulado>       
                <endereco>Av. Dr. Cardoso de Melo 1470 - Conj. 711 - Ed. Net Office - Vila Olímpia, São Paulo-SP</endereco>     
                <cep>04548-005</cep>                
                <fax>(11) 3926-6798</fax>
                <geral>1</geral>
                <honorario>0</honorario>
                <nome_img_bandeira>flag_austria</nome_img_bandeira>
                <url-site></url-site>
                <emails>
                    <email>[email protected]</email>
                </emails>
                <nome-chefia>Dr. Ingomar Lochschmidt (Cônsul), Stefan Nemetz (Vice-Cônsul)</nome-chefia>
                <telefones>
                    <telefone>(11) 3842-7500</telefone>
                </telefones>
                <observacao></observacao>
                <expediente></expediente>
                <jurisdicao></jurisdicao>
            </consulado>
            <consulado>
                <nome-consulado>Consulado-Geral da Áustria em São Paulo - SP - Departamento Comercial</nome-consulado>      
                <endereco>Av. Dr. Cardoso de Melo 1340 - 7º andar - Conj. 71 - Vila Olímpia, São Paulo-SP</endereco>        
                <cep>04548-004</cep>                
                <fax>(11) 3842-5330</fax>
                <geral>1</geral>
                <honorario>0</honorario>
                <nome_img_bandeira>flag_austria</nome_img_bandeira>
                <url-site></url-site>
                <emails>
                    <email>[email protected]</email>
                    <email>[email protected]</email>
                </emails>
                <nome-chefia>Dr. Ingomar Lochschmidt (Cônsul), Stefan Nemetz (Vice-Cônsul)</nome-chefia>
                <telefones>
                    <telefone>(11) 3044-9944</telefone>
                </telefones>
                <observacao></observacao>
                <expediente></expediente>
                <jurisdicao></jurisdicao>
            </consulado>
        </consulados>
    </pais>     
</paises>

XAML

<phone:LongListSelector Name="lstCons"
    HorizontalAlignment="Center" 
    VerticalAlignment="Top" 
    LayoutMode="List" 
    IsGroupingEnabled="False"
    Width="456" SelectionChanged="lstCons_SelectionChanged" >
                <phone:LongListSelector.ItemTemplate>
                    <DataTemplate>
                        <Border BorderBrush="#111" Background="Transparent" Margin="0, 10, 0, 0" BorderThickness="0,0,0,2">
                            <StackPanel x:Name="MainStackPanel" VerticalAlignment="Center" Orientation="Vertical"  >
                                <TextBlock Text="{Binding NomeConsulado}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource PhoneTextTitle3Style}"/>
                                <TextBlock Text="{Binding Endereco}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource PhoneTextSmallStyle}"/>
                                <TextBlock Text="{Binding Cep}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource PhoneTextSmallStyle}"/>
                                <TextBlock Text="{Binding Telefone}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource PhoneTextSmallStyle}"/>
                                <TextBlock Text="{Binding Email}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource PhoneTextSmallStyle}"/>
                            </StackPanel>

                        </Border>

                    </DataTemplate>
                </phone:LongListSelector.ItemTemplate>
            </phone:LongListSelector>
    
asked by anonymous 30.04.2014 / 15:24

3 answers

3

Since the return unit is consulted, it is simpler if we begin direct selection with the consulates, and get the other information in the sense of the ancestor or descendant elements, using the XElement methods to get them:

var consulados =
    (from c in xmlDoc.Descendants("consulado")
     let p = c.Ancestors("pais").Single()
     let nomepais = p.Element("nome-pais").Value
     where nomepais == SSP.Consulado.pais
     select new ListaConsulado.Consulado
     {
         NomePais = nomepais,
         Cep = "Cep: " + c.Element("cep").Value,
         Endereco = c.Element("endereco").Value,
         NomeConsulado = c.Element("nome-consulado").Value,
         Telefone = c.Descendants("telefone").Select(t => t.Value).ToList(),
         Email = c.Descendants("email").Select(t => t.Value).ToList(),
     }).ToList();

Ancestors:

  • Only the ancestor element pais is required, we can reach it using the Ancestors method:

    let p = c.Ancestors("pais").Single()
    

Descendants:

  • To get descendants, we can use the Descendants method:

    Telefone = c.Descendants("telefone").Select(t => t.Value).ToList(),
    Email = c.Descendants("email").Select(t => t.Value).ToList(),
    
30.04.2014 / 15:49
2

I have the impression that you would like to simply populate the list with Pais containing the list of Consulados , here is my suggestion:

var lista = (from p in doc.Root.Elements()
        select new ListaConsulado.Paises
        {
            NomePais = p.Element("nome-pais").Value,
            Consulados = (from c in p.Elements("consulados").Elements()
                         select new ListaConsulado.Consulado
                         {
                             NomeConsulado = c.Element("nome-consulado").Value,
                             Endereco = c.Element("endereco").Value,
                             Cep = c.Element("cep").Value,
                             Telefone = c.Descendants("telefone").Select(m => m.Value).ToList(),
                             Email = c.Descendants("email").Select(m => m.Value).ToList()
                         }).ToList()
        }).ToList();
    
30.04.2014 / 16:06
1

Because you use LINQ, the method Distinct might come in handy. I.e.:

lista.ItemsSource = s.GroupBy(t => t.NomeConsulado).Distinct().ToList();

Note that this method uses the standard comparison between objects to eliminate duplicates - that is, two "equal" consulates can be considered different because they are objects with different references. Thus, it may be advisable to also create a type for the consulates, which overloads the Equals method so that you can distinguish consulates by their values.

    
30.04.2014 / 15:52