none
Wie in xml-Datei filtern und nach Attributen suchen mit LINQ? RRS feed

  • Frage

  • Hallo,
    ich habe eine xml-Datei, welche Ergebnisse von Tests beinhaltet.
    Tests (<test>) können in einer Testgruppe (<testGroup>) zusammengefasst sein oder auch nicht.

    Ich will einen Test - egal ob in einer Gruppe oder nicht - an Hand der ID (z.B. <id>Test_1_1</id>)
    mit LINQ ermitteln und die Startzeit (<test starttime="2014-01-21 19:10:46" ...>) und die Endzeit (<result ... endtime="2014-01-21 19:10:47"</result>) von diesem Test erhalten.

    var xmlDoc = XDocument.Load(xmlFile);

    // hiermit erhalte ich alle vier Tests mit allen Attributen vom unteren Beispiel
    var testQuery1 = from test in xmlDoc.Descendants("test") select test;

    // funktioniert nicht; findet keinen Test
    var testQuery2 = from test in xmlDoc.Descendants("test")
      where test.Attribute("id").Value == "Test_1_1"
      select test;

    Selbst wenn der Test "Test_1_1" gefunden wird, dann sollte noch nach den Attributen starttime und endtime gefiltert werden.
    Hat jemand eine Lösung?


    Alexander

     

    <?xml version="1.0" encoding="ISO-8859-1" ?>
    <testProcess>
      <violation type="1">variant 1</violation>
      <global starttime="2014-01-21 19:10:46" />
      <testGroup>
        <test starttime="2014-01-21 19:10:46" ett="45">
          <step id="1" result="ok">123;</step>
          <step id="2" result="ok">123;</step>
          <result description="no problems" endtime="2014-01-21 19:10:47"</result>
          <id>Test_1_1</id>
          <description>Kompletter Test</description>
          <info>
            <title>Ergebnisse:</title>
          </info>
          <info>
            <title>Parameter:</title>
          </info>
        </test>
        <test starttime="2014-01-21 19:10:48" ett="557">
          <step id="1" result="ok">123;</step>
          <step id="2" result="ok">123;</step>
          <result description="no problems" endtime="2014-01-21 19:10:49"</result>
          id>Test_1_2</id>
          <description>Kompletter Test</description>
          <info>
            <title>Ergebnisse:</title>
          </info>
          <info>
            <title>Parameter:</title>
          </info>
       </test>
      </testGroup>
      <test starttime="2014-01-21 19:10:50" ett="83361">
        <step id="1" result="ok">123;</step>
        <step id="2" result="ok">123;</step>
        <result description="no problems" endtime="2014-01-21 19:10:51"</result>
        <id>Test_2_1</id>
        <description>Kompletter Test</description>
        <info>
          <title>Ergebnisse:</title>
        </info>
        <info>
          <title>Parameter:</title>
        </info>
      </test>
      <test starttime="2014-01-21 19:10:52" ett="83361">
        <step id="1" result="ok">123;</step>
        <step id="2" result="ok">123;</step>
        <result description="no problems" endtime="2014-01-21 19:10:53"</result>
        <id>Test_2_2</id>
        <description>Kompletter Test</description>
        <info>
          <title>Ergebnisse:</title>
        </info>
        <info>
          <title>Parameter:</title>
        </info>
      </test>
    </testProcess>

    Mittwoch, 22. Januar 2014 16:57

Antworten

  • Hallo,
    das Problem besteht darin, das id kein Attribut, sondern ein Unterknoten ist. Nachfolgender Code hohlt die Informationen aus dem Dokument heraus:
    XDocument doc = XDocument.Load(@"D:\test\xmldoc.xml");
    var tests = doc.Descendants("test")
                   .Where(x => x.Element("id").Value == "Test_1_1")
                   .Select(x => new { StartTime = x.Attribute("starttime").Value, EndTime = x.Element("result").Attribute("endtime").Value });
    foreach (var test in tests)
        Console.WriteLine("Start: " + test.StartTime.PadRight (40) + "Ende: " + test.EndTime);
    Wie du siehst, verwede ich hier nochmal die Element-Methode um die Unterschlüssel heraus zu lesen. Am Ende erstelle ich einen anonymen Typen mit den beiden Zeiten. Du solltest eventuell noch ein DateTime daraus erstellen.

    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    • Als Antwort markiert AlexanderRi Donnerstag, 23. Januar 2014 08:18
    Mittwoch, 22. Januar 2014 17:08
    Moderator

Alle Antworten

  • Hi

    schau dir mal die Beispile an.

    Für dich dürfte es etwa so aussehen:

    IEnumerable<XElement> partNos =
        from item in xmlDoc.Descendants("test")
        where (string) item.Element("id") == "Test_1_1 &&
            (DateTime) item.Element("starttime") > DeineDateTime
        select item;

    MFG

    Björn


    • Bearbeitet Palin Mittwoch, 22. Januar 2014 17:08
    Mittwoch, 22. Januar 2014 17:05
  • Hallo,
    das Problem besteht darin, das id kein Attribut, sondern ein Unterknoten ist. Nachfolgender Code hohlt die Informationen aus dem Dokument heraus:
    XDocument doc = XDocument.Load(@"D:\test\xmldoc.xml");
    var tests = doc.Descendants("test")
                   .Where(x => x.Element("id").Value == "Test_1_1")
                   .Select(x => new { StartTime = x.Attribute("starttime").Value, EndTime = x.Element("result").Attribute("endtime").Value });
    foreach (var test in tests)
        Console.WriteLine("Start: " + test.StartTime.PadRight (40) + "Ende: " + test.EndTime);
    Wie du siehst, verwede ich hier nochmal die Element-Methode um die Unterschlüssel heraus zu lesen. Am Ende erstelle ich einen anonymen Typen mit den beiden Zeiten. Du solltest eventuell noch ein DateTime daraus erstellen.

    Koopakiller [kuːpakɪllɐ] (Tom Lambert)
    Webseite | Code Beispiele | Facebook | Twitter | Snippets   C# ↔ VB.NET Konverter
    Markiert bitte beantwortende Posts als Antwort und bewertet Beiträge. Danke.

    • Als Antwort markiert AlexanderRi Donnerstag, 23. Januar 2014 08:18
    Mittwoch, 22. Januar 2014 17:08
    Moderator