Hilfestellung bei Objektmodell

  • Allgemein

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von TheProfessor.

    Hilfestellung bei Objektmodell

    Hallo zusammen,

    momentan entwickle ich einen Parser (hoffe das ist hierfür die richtige Bezeichnung :D) der mir eine bestimmte Zeichenkette einliest und zerlegt. Eine mögliche Zeichenkette wäre Folgende:

    +(Rot/Blau/Grün)+Viereckig+(Leicht/Schwer)+Teuer

    Rauskommen sollen alle möglichen Kombinationen die dieser Term beinhaltet, also:

    Rot, Viereckig, Leicht, Teuer
    Blau, Viereckig, Leicht, Teuer
    usw...


    Die Aufdröselung nach einzelnen Kombinationen funktioniert schon mal einwandfrei. Im nächsten Schritt möchte ich die Ergebnisse aber untereinander vergleichen. Hierfür muss ich mithilfe zugeführter Daten kategorisieren um welchen Typ sich jedes Merkmal handelt damit ich weiß was ich womit vergleich muss, Farbe mit Farbe zum Beispiel. Rot/Blau/Grün sind vom Typ Farbe, Viereckig ist vom Typ Form usw...
    Das ist wichtig für mich weil die Vergleichsmechanismen vom jeweiligen Typ abhängig sind und sich nicht verallgemeinern lassen.

    Hier mein Ansatz:

    Jeder Typ (Farbe, Form, Preis, ...) bekommt eine eigene Klasse spendiert die alle von der Basisklasse "Merkmal" erben. In den jeweiligen Klassen lassen sich sehr bequem die Vergleichsmechanismen realisieren. Das Problem ist jetzt aber der Schritt wie ich überhaupt an ein Objekt des richtigen Typs komme. Zu welchem Typ meine Zeichenkette (z.B. "Blau") gehört lese ich mir aus einer XML-Datei aus:

    XML-Quellcode

    1. <MermalTypen>
    2. <Typ Name="Farbe">
    3. <Value>Blau</Value>
    4. <Value>Rot</Value>
    5. <Value>Grün</Value>
    6. </Typ>
    7. <Typ Name="Form">
    8. <Value>Viereckig</Value>
    9. <Value>Rund</Value>
    10. <Value>Oval</Value>
    11. </Typ>
    12. <Typ Name="Preis">
    13. <Value>Teuer </Value>
    14. <Value>Billig </Value>
    15. </Typ>
    16. <Typ Name="Gewicht">
    17. <Value>Leicht</Value>
    18. <Value>Schwer</Value>
    19. </Typ>
    20. </MermalTypen>


    VB.NET-Quellcode

    1. Private Sub MerkmaleHinzufuegen(MerkmalWerte As List(Of XElement))
    2. For Each MerkmalWertXElement As XElement In MerkmalWerte
    3. Dim MerkmalWertTyp As String = MerkmalWertXElement.@Name
    4. Dim NeuesMerkmal As Merkmal
    5. Select Case MerkmalWert
    6. Case "Farbe"
    7. NeuesMerkmal = New Farbe()
    8. Case "Form"
    9. NeuesMerkmal = New Form()
    10. Case "Preis"
    11. NeuesMerkmal = New Preis()
    12. Case "Gewicht"
    13. NeuesMerkmal = New Gewicht()
    14. Case Else
    15. Throw New ArgumentException(MerkmalWert & " ist nicht im Merkmalsvorrat vorhanden", "MerkmalWerte")
    16. End Select
    17. '...
    18. End Sub



    Obwohl der Ansatz im weiteren Verlauf blendend funktionieren zu scheint so bin ich an dieser Stelle doch noch sehr unzufrieden. Problematisch wird es wenn jetzt weitere Typen hinzukommen was definitiv passieren wird. Ich müsste sowohl Neue Klassen anlegen (Damit könnte ich noch leben) aber auch diese Methode abändern. Auch dass hier nach einem String differenziert wird gefällt mir nicht wirklich. Ich hätte gerne so etwas wie ein Enum dass sich dynamisch erstellt und erweitet und dann jedes mal durchlaufen wird.

    Ja die "Fragestellung" hier ist sehr vage aber vielleicht gibt es ja jemanden dem auf Anhieb ein viel besserer Ansatz einfällt. Bin für alles offen.

    Vielen Dank fürs lesen und für eventuell folgende Beiträge :thumbsup:


    Gruß Tommi
    Hi,

    habe hier mal ne Lösung für dich:

    PHP-Quellcode

    1. <?php
    2. /**
    3. * In Anlehnung an den Code von: https://pmellor.wordpress.com/2013/09/30/working-out-combinations-of-a-multidimensional-array-in-php/
    4. */
    5. function workOutCombinations ($data, &$all = array(), $group = array(), $val = null, $i = 0) {
    6. if (isset($val)) {
    7. array_push($group, $val);
    8. }
    9. if ($i >= count($data)) {
    10. array_push($all, $group);
    11. } else {
    12. foreach ($data[$i] as $v) {
    13. workOutCombinations($data, $all, $group, $v, $i + 1);
    14. }
    15. }
    16. return $all;
    17. }
    18. # Dein String
    19. $str = "+(Rot/Blau/Grün)+Viereckig+(Leicht/Schwer)+Teuer";
    20. if(isset($_POST['str'])){
    21. $str = htmlspecialchars($_POST['str'], ENT_QUOTES);
    22. }
    23. $str = @preg_replace('/^ *\++|\++ *$/i', '', $str);
    24. $arr = @preg_split('/\+/', $str);
    25. $myArray = array();
    26. foreach($arr as $k => $v){
    27. if(@preg_match('/^\(.*?\)$/i', $v)){
    28. $v = @preg_replace('/\(|\)/', '', $v);
    29. $subarr = @preg_split('/\//i', $v);
    30. $arr[] = $subarr;
    31. $myArray[] = $subarr;
    32. }else{
    33. $myArray[] = array($v);
    34. }
    35. }
    36. $combos = workOutCombinations($myArray);
    37. foreach($combos as $c){
    38. echo implode(', ', $c) . "<br>";
    39. }
    40. ?>
    41. <!DOCTYPE html>
    42. <html>
    43. <head>
    44. <title>Test</title>
    45. </head>
    46. <body>
    47. <main>
    48. <hr>
    49. <form method="POST">
    50. <input type="text" name="str" value="<?php echo $str, ENT_QUOTES; ?>" style="width: 90%;"><br>
    51. <input type="submit" value="Submit">
    52. </form>
    53. </main>
    54. </body>
    55. </html>



    Eine Demo zum Sofort-Testen: marius-gerum.de/hurr.php

    String zum Testen: (Rot/Blau/Grün)+Viereckig+(Leicht/Schwer)+Teuer+(Neu/Gebraucht/Neuwertig)+(Bezahlt/Offen)

    Ausgabe im Falle des eben genannten Test-Strings:

    Quellcode

    1. Rot, Viereckig, Leicht, Teuer, Neu, Bezahlt
    2. Rot, Viereckig, Leicht, Teuer, Neu, Offen
    3. Rot, Viereckig, Leicht, Teuer, Gebraucht, Bezahlt
    4. Rot, Viereckig, Leicht, Teuer, Gebraucht, Offen
    5. Rot, Viereckig, Leicht, Teuer, Neuwertig, Bezahlt
    6. Rot, Viereckig, Leicht, Teuer, Neuwertig, Offen
    7. Rot, Viereckig, Schwer, Teuer, Neu, Bezahlt
    8. Rot, Viereckig, Schwer, Teuer, Neu, Offen
    9. Rot, Viereckig, Schwer, Teuer, Gebraucht, Bezahlt
    10. Rot, Viereckig, Schwer, Teuer, Gebraucht, Offen
    11. Rot, Viereckig, Schwer, Teuer, Neuwertig, Bezahlt
    12. Rot, Viereckig, Schwer, Teuer, Neuwertig, Offen
    13. Blau, Viereckig, Leicht, Teuer, Neu, Bezahlt
    14. Blau, Viereckig, Leicht, Teuer, Neu, Offen
    15. Blau, Viereckig, Leicht, Teuer, Gebraucht, Bezahlt
    16. Blau, Viereckig, Leicht, Teuer, Gebraucht, Offen
    17. Blau, Viereckig, Leicht, Teuer, Neuwertig, Bezahlt
    18. Blau, Viereckig, Leicht, Teuer, Neuwertig, Offen
    19. Blau, Viereckig, Schwer, Teuer, Neu, Bezahlt
    20. Blau, Viereckig, Schwer, Teuer, Neu, Offen
    21. Blau, Viereckig, Schwer, Teuer, Gebraucht, Bezahlt
    22. Blau, Viereckig, Schwer, Teuer, Gebraucht, Offen
    23. Blau, Viereckig, Schwer, Teuer, Neuwertig, Bezahlt
    24. Blau, Viereckig, Schwer, Teuer, Neuwertig, Offen
    25. Grün, Viereckig, Leicht, Teuer, Neu, Bezahlt
    26. Grün, Viereckig, Leicht, Teuer, Neu, Offen
    27. Grün, Viereckig, Leicht, Teuer, Gebraucht, Bezahlt
    28. Grün, Viereckig, Leicht, Teuer, Gebraucht, Offen
    29. Grün, Viereckig, Leicht, Teuer, Neuwertig, Bezahlt
    30. Grün, Viereckig, Leicht, Teuer, Neuwertig, Offen
    31. Grün, Viereckig, Schwer, Teuer, Neu, Bezahlt
    32. Grün, Viereckig, Schwer, Teuer, Neu, Offen
    33. Grün, Viereckig, Schwer, Teuer, Gebraucht, Bezahlt
    34. Grün, Viereckig, Schwer, Teuer, Gebraucht, Offen
    35. Grün, Viereckig, Schwer, Teuer, Neuwertig, Bezahlt
    36. Grün, Viereckig, Schwer, Teuer, Neuwertig, Offen


    Code musst halt in VB umwandeln, bin einfach wesentlich fitter in PHP.

    Wenn dann sowieso Typen hinzukommen, die du gar nicht beeinflussen kannst, wird aber das mit der Kategorisierung nicht so wirklich hinhauen 8|
    Theoretisch kannst du die Ausgabe auch als HTML-Tabelle schreiben - fertige js-Bibliotheken mit der man Tabellen sortieren kann gibt's ja genug. Und in VB is sowas eh mit an Bord.


    Link :thumbup:
    Hello World

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Link“ ()

    jo, interessante Anforderung.
    Scheinbar liegt ein 4-dimensionales Kategorisierungs-System vor: Farbe, Form, Gewicht, Preis.
    Und jede Kategorie kann mehrere Werte enthalten.

    Ausserdem liegt eine Abfrage-Grammatik vor:
    + bedeutet "muss enthalten sein" - logisches AND
    ( / ) ist eine Auflistung zulässiger Alternativen - logisches OR
    Werte ohne Klammer entsprechen einer Auflistung mit nur einem Element

    Man kann nun eine Datenmodell der Kategorien anlegen, also 4 Listen, und solch kann man dann auch aus Dateien laden.
    Vermutlich im Datenmodell enthalten sind auch die Artikel, die durch das Kategoriesystem kategorisiert sind.

    Das wäre jdfs besonders einfach, und wohl mal wieder am einfachsten in einem typisierten Dataset zu modellieren.

    Nur der Parser ist eine Herausforderung, da die Grammatik richtig umzusetzen, und auch syntax-widrigen Abfragen abzulehnen.
    Man kann auch einen Abfrage-Assistenten bauen, dem die Kategorien und die möglichen Werte einer jeden bekannt sind, und mit Comboboxen bereitgestellt, dass man von vornherein erst gar keine syntax-widrigen Abfragen zusammenbauen kann.

    Also ich würde empfehlen, zunächstmal in einem typDataset das Datenmodell zu erstellen, und auch schon Haufen Daten einzuspeisen.
    Ob man dann einen Parser baut, oder einen Abfrage-Assistenten kann man dann immer noch überlegen.
    zu typDataset bisserl was zum angugge: vier Views-Videos
    Interessanterweise gibts da ja auch ein Kategorie-System, allerdings ganz primitiv nur eine Kategorie.
    Was das "Abfragen" dann so einfach macht, dass mans garnet mehr als solches erkennt (nämlich ein Parent-Child-View ist eine kategorie-abhängige Abfrage der Artikel)

    Uih - grad nochmal die Filterausdrücke für typDatasets geguckt - also eine geeignete Abfragesprache, die And- und Or-Verknüpfungen unterstützt ist bereits verfügbar!
    EDIT: Erschreckend wie viel Code ich im Gegensatz zur obigen PHP-Version brauche 8|

    Danke für die Antworten, habe beide bis jetzt nur kurz überflogen und noch nicht im Detail durchgearbeitet.

    Falls jemand Interesse hat poste ich hier mal meinen Parser. Ablehnung von widrigen Strings habe ich bis jetzt noch nicht eingebaut (fällt mir komischer Weise am schwersten).

    Die Grammatik hat ErfinderDesRades hier schon richtig aufgezeichnet:
    + bedeutet "muss enthalten sein" - logisches AND
    ( / )ist eine Auflistung zulässiger Alternativen - logisches OR
    Werte ohne Klammer entsprechen einer Auflistung mit nur einem Element
    - bedeutet einen ausschluss - logisches NOT (habe ich im Beispiel nicht aufgeführt)

    Die Funktion habe ich so aufgebaut, dass Sie die ganze Zeichenkette betrachtet, entscheidet welcher Typ vorliegt, auf den entsprechenden Typ reagiert (meistens in Teilzeichenketten zerlegt) und sich selbst erneut aufruft.
    Folgende Typen gibt es:

    ODER - Wie oben beschrieben Auflistung einzelner Attribute
    KLAMMER - Eingeklammerte Zeichenkette, muss aufgelöst werden da auch Klammern mit "-" angeschrieben werden können und sich somit die Vorzeichen der innen liegenden Zeichenketten umdrehen
    MERKMAL- Einzelner Merkmalwert mit/ohne Vorzeichen
    VERKETTUNG - Mix aus den drei oberen Typen

    VB.NET-Quellcode

    1. Protected Friend Function ZeichenketteAnalysieren(ByVal Zeichenkette As String) As List(Of Konfiguration)
    2. Try
    3. Dim lstKonfigurationen As New List(Of Konfiguration)
    4. If Oder(Zeichenkette) = True Then
    5. Dim lstOderZeichenketten As New List(Of String)
    6. lstOderZeichenketten = OderZerlegen(Zeichenkette)
    7. For Each OderZeichenkette As String In lstOderZeichenketten
    8. lstKonfigurationen.AddRange(ZeichenketteAnalysieren(OderZeichenkette))
    9. Next OderZeichenkette
    10. ElseIf Klammer(Zeichenkette) = True Then
    11. Zeichenkette = KlammerEntfernen(Zeichenkette)
    12. lstKonfigurationen = ZeichenketteAnalysieren(Zeichenkette)
    13. ElseIf Merkmal(Zeichenkette) = True Then
    14. lstKonfigurationen.Add(MerkmalAuslesen(Zeichenkette, Me.Merkmalsvorrat))
    15. ElseIf Verkettung(Zeichenkette) = True Then
    16. Dim lstTeilstrings As New List(Of String)
    17. Dim lstKonfigurationenListen As New List(Of List(Of Konfiguration))
    18. lstTeilstrings = VerkettungZerlegen(Zeichenkette)
    19. For Each Teilstring As String In lstTeilstrings
    20. lstKonfigurationenListen.Add(ZeichenketteAnalysieren(Teilstring))
    21. Next Teilstring
    22. lstKonfigurationen = KonfigurationenAusmultiplizieren(lstKonfigurationenListen)
    23. End If
    24. Return lstKonfigurationen
    25. Catch ex As Exception
    26. Throw New ArgumentException(Zeichenkette & " konnte nicht eingelesen werden." & vbCrLf & vbCrLf & ex.Message, ex)
    27. End Try
    28. End Function
    29. ''' <summary>
    30. ''' Prüft ob ein 'ODER' vorliegt
    31. ''' </summary>
    32. ''' <param name="Zeichenkette"></param>
    33. ''' <returns></returns>
    34. ''' <remarks></remarks>
    35. Protected Friend Shared Function Oder(Zeichenkette As String) As Boolean
    36. Dim intAktuelleEbene As Integer = 0
    37. For Each Zeichen As Char In Zeichenkette
    38. If Zeichen = "(" Then : intAktuelleEbene += 1
    39. ElseIf Zeichen = ")" Then : intAktuelleEbene -= 1
    40. ElseIf Zeichen = "/" AndAlso intAktuelleEbene = 0 Then : Return True : End If
    41. Next Zeichen
    42. Return False
    43. End Function
    44. ''' <summary>
    45. ''' Prüft ob eine 'KLAMMER' vorliegt
    46. ''' </summary>
    47. ''' <param name="Zeichenkette"></param>
    48. ''' <returns></returns>
    49. ''' <remarks></remarks>
    50. Protected Friend Shared Function Klammer(Zeichenkette As String) As Boolean
    51. Dim bolBeginn As Boolean = False
    52. Dim intAktuelleEbene As Integer = 0
    53. Dim Zeichen As Char
    54. For Zeichenindex As Integer = 0 To Zeichenkette.Length - 1
    55. Zeichen = Zeichenkette(Zeichenindex)
    56. If {"+", "-", "("}.Contains(Zeichen) = False AndAlso bolBeginn = False Then Return False
    57. If Zeichen = "(" Then bolBeginn = True
    58. If Zeichen = "(" Then intAktuelleEbene += 1
    59. If Zeichen = ")" Then intAktuelleEbene -= 1
    60. If intAktuelleEbene = 0 AndAlso bolBeginn = True AndAlso Zeichenindex < Zeichenkette.Length - 2 Then Return False
    61. Next Zeichenindex
    62. If intAktuelleEbene = 0 Then
    63. Return True
    64. Else
    65. Return False
    66. End If
    67. End Function
    68. ''' <summary>
    69. ''' Prüft ob ein 'Merkmal' vorliegt
    70. ''' </summary>
    71. ''' <param name="Zeichenkette"></param>
    72. ''' <returns></returns>
    73. ''' <remarks></remarks>
    74. Protected Friend Shared Function Merkmal(Zeichenkette As String) As Boolean
    75. For Zeichenindex As Integer = 0 To Zeichenkette.Length - 1
    76. If Zeichenindex > 0 AndAlso {"+", "/", "(", ")"}.Contains(Zeichenkette(Zeichenindex)) Then Return False
    77. Next Zeichenindex
    78. Return True
    79. End Function
    80. ''' <summary>
    81. ''' Prüft ob eine 'VERKETTUNG' vorliegt
    82. ''' </summary>
    83. ''' <param name="Zeichenkette"></param>
    84. ''' <returns></returns>
    85. ''' <remarks></remarks>
    86. Protected Friend Shared Function Verkettung(Zeichenkette As String) As Boolean
    87. If Oder(Zeichenkette) = False AndAlso Klammer(Zeichenkette) = False AndAlso Merkmal(Zeichenkette) = False Then
    88. Return True
    89. Else
    90. Return False
    91. End If
    92. End Function
    93. ''' <summary>
    94. ''' Prüft ob die Klammersetzung der übergebeben Zeichenkette konsistent ist. Löst einen Fehler auf falls die nicht der Fall ist.
    95. ''' </summary>
    96. ''' <param name="Zeichenkette"></param>
    97. ''' <remarks></remarks>
    98. Protected Friend Shared Sub KlammersetzungKontrollieren(Zeichenkette As String)
    99. Dim intEbene As Integer = 0
    100. For Each Zeichen As Char In Zeichenkette
    101. If Zeichen = "(" Then
    102. intEbene += 1
    103. ElseIf Zeichen = ")" Then
    104. intEbene -= 1
    105. End If
    106. Next Zeichen
    107. If intEbene <> 0 Then Throw New ArgumentException("Klammersetzung ist inkonsistent:" & vbCrLf & Zeichenkette)
    108. End Sub
    109. ''' <summary>
    110. ''' Gibt eine Liste von Zeichenketten zurück die durch das übergebene 'ODER' verbunden waren
    111. ''' </summary>
    112. ''' <param name="OderZeichenkette"></param>
    113. ''' <returns></returns>
    114. ''' <remarks></remarks>
    115. Protected Friend Shared Function OderZerlegen(OderZeichenkette As String) As List(Of String)
    116. Try
    117. If BeziehungswissenTerm.Oder(OderZeichenkette) = False Then Throw New ArgumentException("Übergebene Zeichenkette ist kein 'Oder'", "OderZeichenkette")
    118. KlammersetzungKontrollieren(OderZeichenkette)
    119. Dim intEbene As Integer = 0
    120. Dim intAnfangIndex As Integer
    121. Dim intEndeIndex As Integer
    122. Dim lstPositionenOderZeichen As New List(Of Integer)
    123. Dim lstOderStrings As New List(Of String)
    124. For Zeichenindex As Integer = 0 To OderZeichenkette.Length - 1
    125. If OderZeichenkette(Zeichenindex) = "(" Then intEbene += 1
    126. If OderZeichenkette(Zeichenindex) = ")" Then intEbene -= 1
    127. If OderZeichenkette(Zeichenindex) = "/" AndAlso intEbene = 0 Then lstPositionenOderZeichen.Add(Zeichenindex)
    128. Next Zeichenindex
    129. For OderZeichenIndex As Integer = 0 To lstPositionenOderZeichen.Count
    130. If OderZeichenIndex = 0 Then
    131. intAnfangIndex = 0
    132. intEndeIndex = lstPositionenOderZeichen(OderZeichenIndex)
    133. ElseIf OderZeichenIndex = lstPositionenOderZeichen.Count Then
    134. intAnfangIndex = lstPositionenOderZeichen(OderZeichenIndex - 1) + 1
    135. intEndeIndex = OderZeichenkette.Length
    136. Else
    137. intAnfangIndex = lstPositionenOderZeichen(OderZeichenIndex - 1) + 1
    138. intEndeIndex = lstPositionenOderZeichen(OderZeichenIndex)
    139. End If
    140. lstOderStrings.Add(OderZeichenkette.Substring(intAnfangIndex, intEndeIndex - intAnfangIndex))
    141. Next OderZeichenIndex
    142. Return lstOderStrings
    143. Catch ex As Exception
    144. Throw New ArgumentException("Fehler bei Oder-Zerlegung:" & vbCrLf & "Zeichenkette: " & OderZeichenkette & vbCrLf & ex.Message, ex)
    145. End Try
    146. End Function
    147. ''' <summary>
    148. ''' Gibt eine Zeichenkette ohne oberste Klammerebene zurück
    149. ''' </summary>
    150. ''' <param name="KlammerZeichenkette"></param>
    151. ''' <returns></returns>
    152. ''' <remarks></remarks>
    153. Protected Friend Shared Function KlammerEntfernen(ByVal KlammerZeichenkette As String) As String
    154. Try
    155. If BeziehungswissenTerm.Klammer(KlammerZeichenkette) = False Then Throw New ArgumentException("Übergebene Zeichenkette ist keine 'Klammer'", "KlammerZeichenkette")
    156. KlammersetzungKontrollieren(KlammerZeichenkette)
    157. Dim intIndexErsteKlammer As Integer
    158. Dim intAktuelleEbene As Integer = 0
    159. Dim strErsetzenderOperator As String
    160. For Zeichenindex As Integer = 0 To KlammerZeichenkette.Length - 1
    161. If KlammerZeichenkette(Zeichenindex) = "(" Then
    162. intIndexErsteKlammer = Zeichenindex
    163. Exit For
    164. End If
    165. Next Zeichenindex
    166. If intIndexErsteKlammer > 0 AndAlso KlammerZeichenkette(intIndexErsteKlammer - 1) = "-" Then
    167. strErsetzenderOperator = "+-"
    168. Else
    169. strErsetzenderOperator = "+"
    170. End If
    171. For IndexZeichen As Integer = KlammerZeichenkette.Length - 1 To intIndexErsteKlammer + 1 Step -1
    172. If KlammerZeichenkette(IndexZeichen) = "(" Then intAktuelleEbene += 1
    173. If KlammerZeichenkette(IndexZeichen) = ")" Then intAktuelleEbene -= 1
    174. If KlammerZeichenkette(IndexZeichen) = "," Then
    175. KlammerZeichenkette = KlammerZeichenkette.Remove(IndexZeichen, 1)
    176. KlammerZeichenkette = KlammerZeichenkette.Insert(IndexZeichen, strErsetzenderOperator)
    177. End If
    178. Next IndexZeichen
    179. Return KlammerZeichenkette.Substring(intIndexErsteKlammer + 1, KlammerZeichenkette.Length - intIndexErsteKlammer - 2)
    180. Catch ex As Exception
    181. Throw New ArgumentException("Fehler bei Klammer-Zerlegung:" & vbCrLf & "Zeichenkette: " & KlammerZeichenkette & vbCrLf & ex.Message, ex)
    182. End Try
    183. End Function
    184. ''' <summary>
    185. ''' Gibt eine Liste von Zeichenketten zurück die durch eine 'VERKETTUNG' verbunden waren
    186. ''' </summary>
    187. ''' <param name="VerkettungZeichenkette"></param>
    188. ''' <returns></returns>
    189. ''' <remarks></remarks>
    190. Protected Friend Shared Function VerkettungZerlegen(VerkettungZeichenkette As String) As List(Of String)
    191. Try
    192. If BeziehungswissenTerm.Verkettung(VerkettungZeichenkette) = False Then Throw New ArgumentException("Übergebene Zeichenkette ist keine 'Verkettung'", "VerkettungZeichenkette")
    193. KlammersetzungKontrollieren(VerkettungZeichenkette)
    194. Dim intEbene As Integer = 0
    195. Dim intAnfangIndex As Integer
    196. Dim intEndeIndex As Integer
    197. Dim intLaenge As Integer
    198. Dim lstPositionenUndZeichen As New List(Of Integer)
    199. Dim lstUndStrings As New List(Of String)
    200. For Zeichenindex As Integer = 1 To VerkettungZeichenkette.Length - 1
    201. If VerkettungZeichenkette(Zeichenindex) = "(" Then intEbene += 1
    202. If VerkettungZeichenkette(Zeichenindex) = ")" Then intEbene -= 1
    203. If VerkettungZeichenkette(Zeichenindex) = "+" AndAlso intEbene = 0 Then lstPositionenUndZeichen.Add(Zeichenindex)
    204. Next Zeichenindex
    205. For UndZeichenIndex As Integer = 0 To lstPositionenUndZeichen.Count
    206. If UndZeichenIndex = 0 Then
    207. intAnfangIndex = 0
    208. intEndeIndex = lstPositionenUndZeichen(UndZeichenIndex)
    209. intLaenge = intEndeIndex - intAnfangIndex
    210. ElseIf UndZeichenIndex = lstPositionenUndZeichen.Count Then
    211. intAnfangIndex = lstPositionenUndZeichen(UndZeichenIndex - 1)
    212. intEndeIndex = VerkettungZeichenkette.Length
    213. intLaenge = intEndeIndex - intAnfangIndex
    214. Else
    215. intAnfangIndex = lstPositionenUndZeichen(UndZeichenIndex - 1)
    216. intEndeIndex = lstPositionenUndZeichen(UndZeichenIndex)
    217. intLaenge = intEndeIndex - intAnfangIndex
    218. End If
    219. lstUndStrings.Add(VerkettungZeichenkette.Substring(intAnfangIndex, intLaenge))
    220. Next UndZeichenIndex
    221. Return lstUndStrings
    222. Catch ex As Exception
    223. Throw New ArgumentException("Fehler bei Verkettung-Zerlegung:" & vbCrLf & "Zeichenkette: " & VerkettungZeichenkette & vbCrLf & ex.Message, ex)
    224. End Try
    225. End Function
    226. ''' <summary>
    227. ''' Gibt eine Konfiguration zurück die aus dem Merkmal besteht das in der Zeichenkette vorlag
    228. ''' </summary>
    229. ''' <param name="MerkmalZeichenkette"></param>
    230. ''' <returns></returns>
    231. ''' <remarks></remarks>
    232. Friend Shared Function MerkmalAuslesen(MerkmalZeichenkette As String, Merkmalsvorrat As Merkmalsvorrat) As Konfiguration
    233. If BeziehungswissenTerm.Merkmal(MerkmalZeichenkette) = False Then Throw New ArgumentException("Übergebene Zeichenkette ist kein 'Merkmal'", "MerkmalZeichenkette")
    234. KlammersetzungKontrollieren(MerkmalZeichenkette)
    235. Dim Konfiguartion As New Konfiguration
    236. Dim intIndexAnfang As Integer
    237. Dim bolNegation As Boolean
    238. If MerkmalZeichenkette(0) = "+" Then
    239. If MerkmalZeichenkette(1) = "-" Then
    240. intIndexAnfang = 2
    241. bolNegation = True
    242. Else
    243. intIndexAnfang = 1
    244. bolNegation = False
    245. End If
    246. Else
    247. If MerkmalZeichenkette(0) = "-" Then
    248. intIndexAnfang = 1
    249. bolNegation = True
    250. Else
    251. intIndexAnfang = 0
    252. bolNegation = False
    253. End If
    254. End If
    255. Konfiguartion.MerkmalHinzufuegen(Merkmalsvorrat.GetMerkmalObjekt(MerkmalZeichenkette.Substring(intIndexAnfang, MerkmalZeichenkette.Length - intIndexAnfang), bolNegation))
    256. Return Konfiguartion
    257. End Function

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „TheProfessor“ ()

    aber was sagst du zu meinen weitergehenden Überlegungen, dass deine Grammatik zwar schön und gut ist, dass aber mit DataExpressions bereits eine Grammatik vorliegt, die alles das abdeckt?

    Der Filter-Ausdruck etwa für deine Query in post#1 sähe so aus:
    Farbe in (1,2,3) And Form = 2 And Gewicht in (0,2) And Preis = 3
    Die Zahlen hierbei wären Verweise auf DataRows, die entweder Farben, Formen, Gewichte oder Preise definieren.
    Für einen FilterAusdruck könnte man auch einen Assistenten coden, ich schätze die Gesamt-Geschichte auf vlt 100 Zeilen Code, und dann ist der Filter erstellt und bereits angewendet und du siehst das Filtrat.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Die Grammatik ist bereits über eine recht bekannte Unternehmenssoftware vorgegeben, die Idee kommt nicht von mir. Ich bekomme Strings die so aussehen. Dein Vorschlag ist natürlich sehr viel bequemer zu handlen aber eine Wahl habe ich an dieser Stelle nicht. Einen Parser brauche ich in jedem Fall.