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

Asked

Viewed 285 times

6

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

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 countries:

Paises

That when selected one, goes to the list of Consulates

"Gambiarra"

And this one, with the "gambiarra":

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

Sem "Gambiarra"

I wanted to know, if there is a way to improve this, why I think that this is not the right way. 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>
  • Yes, there was a change in XML @Fccdias; I suggest you give a solution answer

3 answers

3


Since the return unit are consulates, it is simpler if we start the direct selection with the consulates, and obtain the other information, in the sense of the ancestral or descending elements, using Xelement’s methods to obtain 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 ancestral element pais is necessary, we can get to it using the method Ancestors:

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

Descendants:

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

    Telefone = c.Descendants("telefone").Select(t => t.Value).ToList(),
    Email = c.Descendants("email").Select(t => t.Value).ToList(),
    
  • So, in his own way, he brings all the consulates, and I want him to bring the consulate of the parents I want. For example: I select the item "Austria", I will only want the consulates of "Austria"

  • Really, missed the where... I will correct.

  • I put the where as it was in your question... so that now, it will be possible to filter by the name of the country.

  • Perfect. Thank you!

  • Miguel, for me to add the phones in Textblock, what do I need to do? I edited the question with the XAML

  • You can create another property in the class ListaConsulado.Consulado that concatenates the list strings into a single string, and then uses this property in XAML.

  • 1

    In class: public string TelefoneStr { get { return string.Join("; ", this.Telefone); } } in the XAML: <TextBlock Text="{Binding TelefoneStr}" ... "/>

  • Miguel, the need arose to put type: Phones: 14141414; 656656565; 65656565.... How do I add the text "Phones" before the numbers?

  • 1

    If you used the suggestion to create a property TelefoneStr, just concatenate the string first: public string TelefoneStr { get { return "Telefones: " + string.Join("; ", this.Telefone); } }

Show 4 more comments

2

I have the impression that you would like to simply fill out the list with Pais containing the list of Consulados, follows 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();

1

Once 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. It may therefore also be advisable to create a type for consulates, which burdens the method Equals so that you can distinguish consulates by the values of them.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.