XML duplicating the reading of the results

Asked

Viewed 90 times

4

I have a XML:

<paises>
<pais>
    <nome-pais>África do Sul</nome-pais>
    <consulados>        
        <consulado>
            <nome-consulado>Consulado da República da África do Sul</nome-consulado>        
            <endereco>Av. Paulista 1754, 12º andar</endereco>       
            <cep>01310-100</cep>
            <telefones>
                <telefone>(11)3265-0449</telefone>
                <telefone>(11)3265-0540</telefone>
            </telefones>
        </consulado>
    </consulados>
</pais>
<pais>
    <nome-pais>Albânia</nome-pais>  
    <consulados>        
        <consulado>
            <nome-consulado>Consulado da República da Albânia</nome-consulado>                  
            <cep>01310-100</cep>
            <telefone>(11) 3283-3305</telefone>
        </consulado>
    </consulados>
</pais>

When I go to read the phones, it always doubles:

Duplica a lista

Code C#:

XDocument xmlDoc = XDocument.Load(XmlReader.Create(@"XML\consulados_pt.xml"));
 var result2 = (from p in xmlDoc.Descendants("pais") 
                let Nomepais = p.Element("nome-pais").Value
                from f in xmlDoc.Descendants("telefones")
                                .SelectMany(x=> x.Elements("telefone")
                                .Select(t=>t.Value))
                let telefone = f    
                where Nomepais == SSP.Consulado.pais                
                select new ListaConsulado.Consulado()
                    {
                        NomePais = Nomepais,
                        Telefone = "Tel: " + telefone
                    }
                ).ToList();

Obs: I put this code let telefone = f just for testing!

  • I wanted to get both phones, without duplicating the list
  • And there’s another detail, when I open up another item on the list, he brings these same phones:

Mesmos telefones

<telefone>(11)3265-0449</telefone>
<telefone>(11)3265-0540</telefone>

XAML em caso de dúvidas

<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  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}"/>
                            </StackPanel>
                        </Border>
                    </DataTemplate>
                </phone:LongListSelector.ItemTemplate>
            </phone:LongListSelector>

1 answer

1


The problem is in the assignment telefone = f.Element("telefone").Value, for the method Element returns only one element, in which case it will be the first one found.

Instead, use the method Elements, and the LINQ method SelectMany to create the list with the phones:

var result2 = xmlDoc.Descendants("telefones")
    .SelectMany(
        x => x.Elements("telefone")
            .Select(t => t.Value))
    .ToList();

EDIT

In the case could use the following, to obtain each consulate, with the name of the corresponding country, and the respective phones:

var consuladosComTelefones = xmlDoc
    .Element("paises")
    .Elements("pais")
    .SelectMany(
        p => p.Element("consulados") == null ? null : p.Element("consulados")
            .Elements("consulado")
            .Select(c => new ListaConsulado.Consulado
            {
                NomePais = p.Element("nome-pais").Value,
                Telefone = c.Element("telefones") == null ? null : c.Element("telefones")
                    .Elements("telefone")
                    .Select(t => t.Value).ToList(),
            })).ToList();

Assuming the consulate class is like this:

public class Consulado
{
    public string NomePais { get; set; }
    public List<string> Telefone { get; set; }
}
  • I edited the answer, using structured query in Xdocument using methods Element and Elements, in addition to the methods Select and SelectMany LINQ. So the XML reading is better structured... I think.

  • You are returning the following error: Additional information: Object reference not set to an instance of an object.

  • I typed the name of the wrong property! Fixed... also put some checks if XML is incomplete.

Browser other questions tagged

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