Die Community zu .NET und Classic VB.
Menü

Tipp-Upload: VB.NET 0164: VB 2008 - Linq/XML: Gruppenweises aggregieren

 von 

Hinweis zum Tippvorschlag  

Dieser Vorschlag wurde noch nicht auf Sinn und Inhalt überprüft und die Zip-Datei wurde noch nicht auf schädlichen Inhalt hin untersucht.
Bitte haben Sie ein wenig Geduld, bis die Freigabe erfolgt.

Über den Tipp  

Dieser Tippvorschlag ist noch unbewertet.

Der Vorschlag ist in den folgenden Kategorien zu finden:

  • Datenbanken und XML
  • Sprachmerkmale

Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
Aggregate, Linq, XML, XElement, Linq to XML, Group By

Der Vorschlag wurde erstellt am: 26.12.2007 11:50.
Die letzte Aktualisierung erfolgte am 08.04.2008 13:23.

Zurück zur Übersicht

Beschreibung  

Ein keines Beispiel zu Linq to XML sowie den Linq-Operatoren Group By und Aggregate, mit Hilfe derer man recht logisch z.B. statistische Informationen aus Enumerationen ziehen kann.

Dazu interessant: http://www.microsoft.com/germany/msdn/library/visualtools/VorschauAufVisualBasic90.mspx?mfr=true

Schwierigkeitsgrad

Schwierigkeitsgrad 3

Verwendete API-Aufrufe:

Download:

Download des Beispielprojektes [12,86 KB]

' Dieser Source stammt von http://www.activevb.de
' und kann frei verwendet werden. Für eventuelle Schäden
' wird nicht gehaftet.

' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
' Ansonsten viel Spaß und Erfolg mit diesem Source!
'
' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird.
' In den Zip-Dateien ist er jedoch zu finden.

' ------------ Anfang Projektgruppe XMLGroup.sln  ------------
' ----------- Anfang Projektdatei XMLGroup.vbproj  -----------
' ------------------ Anfang Datei Form1.vb  ------------------
Option Strict On

Public Class Form1

    Private Families As New FamilyCollection

    Sub Init()

        ' Zurücksetzen
        Families.Reset()

        ' Hilfe ;-)
        ' Initialisierung mit reinem VB
        Dim Family As Family = New Family() With { .Name = "Mustermann", .Members = New List( _
            Of Person)(New Person() { New Person() With { .Name = "Max", .Role = "Vater", _
            .Age = 45 }, New Person() With { .Name = "Maxima", .Role = "Mutter", .Age = 45 } _
            } ), .Children = New List(Of Person)(New Person() { New Person() With { .Name = _
            "Markus", .Role = "Sohn", .Age = 10 }, New Person() With { .Name = "Martha", _
            .Role = "Tochter", .Age = 12 } }) }

        Families.NextFamily = Family

        ' Schon besser
        ' XML-Initialisierung
        Families.NextXMLFamily = <Family Name="Unbekannt">
        <Member Name="Mr.  X" Role="Vater" Age="61"/>
        <Member Name="Mrs. Y" Role="Mutter" Age="58"/>
        <Children>
        <Child Name="Tick" Role="Sohn" Age="8"/>
        <Child Name="Trick" Role="Sohn" Age="9"/>
        <Child Name="Track" Role="Sohn" Age="10"/>
        </Children>
        </Family>

        ' Ausgeben
        TextBox1.Text = Families.ToString

    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Init()

    End Sub

    Private Sub MakeQuery()

        ' Ganz viele Informationen nach Familien gruppiert ermitteln
        Dim QueryVector = From Child In Families.XML...<Child> Group By _
            Child.Parent.Parent.@Name Into Children = Group, AverageAge = Average( _
            Integer.Parse(Child.@Age)), Oldest = Max(Integer.Parse(Child.@Age)), Youngest = _
            Min(Integer.Parse(Child.@Age)), HasDauthers = Any(Child.@Role = "Tochter"), _
            NumSons = Count(Child.@Role = "Sohn")

        ' Mittleres Alter der Väter herausfinden
        Dim MittleresAlter = Aggregate Father In (From Member In Families.XML...<Member> _
            Where Member.@Role = "Vater" Select Member) Into AverageAge = Average( _
            Integer.Parse(Father.@Age))

        TextBox2.Text = String.Format("Das mittlere Alter aller Väter der genannten " & _
            "Familien beträgt {0} Jahre{1}{1}", MittleresAlter, Environment.NewLine)

        ' Die anderen Informationen pro Familie durchlaufen und ausgeben
        For Each Result In QueryVector

            With Result

                Dim Res As String = String.Format(String.Join(Environment.NewLine, New _
                    String() { "Das älteste Kind der Familie ""{0}"" ist {1} Jahre alt", _
                    "Das jüngste Kind ist {2} Jahre alt", "Das mittlere Alter der Kinder " & _
                    "ist {3} Jahre", "Die Familie hat {4}Töchter und {5} {6}", "", "Die " & _
                    "Namen der Kinder lauten: ", "> {7}" } ), .Name, .Oldest, .Youngest, _
                    .AverageAge, IIf(.HasDauthers, "", "keine "), .NumSons, IIf(.NumSons = 1, _
                    "Sohn", "Söhne"), String.Join (Environment.NewLine & "> ", _
                    .Children.ToList.ConvertAll(Of String)(Function(x As XElement) _
                    String.Format( "{0} ({1} Jahre)", x.@Name, x.@Age)).ToArray))

                TextBox2.Text &= Res & Environment.NewLine & Environment.NewLine & _
                    Environment.NewLine

            End With

        Next

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles Button2.Click

        Application.Exit()

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles Button1.Click

        MakeQuery()

    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles Button3.Click

        Init()

    End Sub

End Class

' ------------------- Ende Datei Form1.vb  -------------------
' ------------------- Anfang Datei Test.vb -------------------
Option Infer On
Option Strict On
Option Explicit On

Class FamilyCollection

    Private XMLDoc As XElement = <Families></Families>

    Public WriteOnly Property NextXMLFamily() As XElement
        Set(ByVal value As XElement)
            XMLDoc.Add(value)

        End Set

    End Property

    Public Sub Reset()

        XMLDoc = <Families></Families>

    End Sub

    ' Linq to XML
    ' Mit ASP-Style XML-Code erstellen
    Public WriteOnly Property NextFamily() As Family
        Set(ByVal Family As Family)
            NextXMLFamily = <Family Name=<%= Family.Name %>>

            <%= From Member As Person In Family.Members Where Member.Role = "Vater" Or _
                Member.Role = "Mutter" Select <Member Name=<%= Member.Name %> Role=<%= _
                Member.Role %> Age=<%= Member.Age %>/> %>

            <Children>

            <%= From Child As Person In Family.Children Where Child.Role = "Sohn" Or _
                Child.Role = "Tochter" Select <Child Name=<%= Child.Name %> Role=<%= _
                Child.Role %> Age=<%= Child.Age %>/> %>

            </Children>
            </Family>

        End Set

    End Property

    Public Overrides Function ToString() As String

        Return XMLDoc.ToString

    End Function

    Public ReadOnly Property XML() As XElement
        Get
            Return XMLDoc

        End Get

    End Property

End Class

Class Family

    Public Name As String
    Public Members As List(Of Person)
    Public Children As List(Of Person)

End Class

Class Person

    Public Name As String
    Public Role As String
    Public Age As Integer

End Class

' -------------------- Ende Datei Test.vb --------------------
' ------------ Ende Projektdatei XMLGroup.vbproj  ------------
' ------------- Ende Projektgruppe XMLGroup.sln  -------------

	

Diskussion  

Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.

Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.