Skocz do zawartości

Recommended Posts

Napisano

Witam,
mam takiego xml'a jak poniżej. Próbuje napisać zapytanie dzięki któremu mógłbym uzyskać takiego outputa:
12 10 11 5 01 1 AN 0454741
10 05 06 2 00 1 SW 0729103
26 05 04 2 01 1 G 0264443

Próbowałem zrobić to tak:
 

var xml = XDocument.Load(@"test.xml");

            var query = from c in xml.Descendants()
                // where (string)c.Attribute("name") == "WOJ"
                select new
                {
                    name1 = ((string)c.Attribute("name") == "name1")? c.Value : string.Empty,
                    name2 = ((string)c.Attribute("name") == "name2") ? c.Value : string.Empty,
                    name3 = ((string)c.Attribute("name") == "name3") ? c.Value : string.Empty
...
                };

            foreach (var item in query)
            {
                Console.WriteLine(item.name1 + " " + item.name2 + " " + item.name3 ...);
            }



ale nie działa:/ Moglibyście pomóc?
 

<?xml version="1.0" encoding="UTF-8"?>
<root>
<catalog name="test" type="all" date="2016-01-01">
<row>
<col name="name1">12</col>
<col name="name2">10</col>
<col name="name3">11</col>
<col name="name4">5</col>
<col name="name5">01</col>
<col name="name6">1</col>
<col name="name7">AN</col>
<col name="name8">0454741</col>
<col name="name9">0454741</col>
<col name="name10">2016-01-01</col>
</row>
<row>
<col name="name1">10</col>
<col name="name2">05</col>
<col name="name3">06</col>
<col name="name4">2</col>
<col name="name5">00</col>
<col name="name6">1</col>
<col name="name7">SW</col>
<col name="name8">0729103</col>
<col name="name9">0729095</col>
<col name="name10">2016-01-01</col>
</row>
<row>
<col name="name1">26</col>
<col name="name2">05</col>
<col name="name3">04</col>
<col name="name4">2</col>
<col name="name5">01</col>
<col name="name6">1</col>
<col name="name7">G</col>
<col name="name8">0264443</col>
<col name="name9">0264443</col>
<col name="name10">2016-01-01</col>
</row>
</catalog>
</root> 



 

Napisano

Wydaje mi się, że iterowanie po wszystkich węzłach i wyciąganie danych tylko z tych węzłów, które nas interesują nie jest najlepszym pomysłem. Lepiej wyciągnąć tylko węzły znaczące, np. najpierw stworzyć kolekcję węzłów row i następnie z nich wyciągać te węzły col które mają dla zadanego atrybutu konkretne wartości - np. wszystkie col które w wartości atrybutu name zawierają ciąg 'name'. Można to zrobić takim np. zapytaniem (wyświetli wyciągnięte dane oddzielone spacją):

List<string> rowsDetails =
                xml.Descendants()
                   .Where(x => x.Name == "row")
                   .Select(row =>
                        string.Join(" ", row.Descendants()
                                            .Where(x => x.Name == "col" && ((string)x.Attribute("name")).Contains("name"))
                                            .Select(y => y.Value)
                        )
                    ).ToList();

rowsDetails.ForEach(Console.WriteLine);

Oczywiście jeżeli zamierzamy robić coś więcej z danymi z XMLa to zamiast List<string> należy użyć listy obiektów prezentujących dane z każdego wiersza - np List<RowDetail> i wówczas można to zrobić tak:

public class RowDetails
{
  public string Name1 { get; set; }
  public string Name2 { get; set; }
  public string Name3 { get; set; }
  ...
}
...
List<RowDetails> rowsDetails = xml.Descendants().Where(x => x.Name == "row").Select(row =>
{
  var desc = row.Descendants().Where(x => x.Name == "col");
  var xElements = desc as List<XElement> ?? desc.ToList();

  var n1 = xElements.FirstOrDefault(x => (string)x.Attribute("name") == "name1")?.Value;
  var n2 = xElements.FirstOrDefault(x => (string)x.Attribute("name") == "name2")?.Value;
  var n3 = xElements.FirstOrDefault(x => (string)x.Attribute("name") == "name3")?.Value;
  ...
    
  return new RowDetails()
  {
  	Name1 = n1,
  	Name2 = n2,
  	Name3 = n3
    ...
  };
}).ToList();

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gość
Odpowiedz...

×   Wkleiłeś zawartość bez formatowania.   Usuń formatowanie

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Utwórz nowe...