Zum Hauptinhalt springen

2.5. Segments (Segmente)

2.5. Segments (Segmente)

Für jeden Knoten in einer Eingabe-Knotenliste wenden Segmente einen oder mehr Selektoren auf den Knoten an und verketten die Ergebnisse jedes Selektors zu pro-Eingabe-Knoten-Knotenlisten, die dann in der Reihenfolge der Eingabe-Knotenliste verkettet werden, um eine einzelne Segmentergebnis-Knotenliste zu bilden.

Es zeigt sich: Je mehr Segmente eine Abfrage hat, desto größer die Tiefe der Knoten der resultierenden Knotenliste im Eingabewert:

  • Eine Abfrage mit N Segmenten, N >= 0, erzeugt eine Knotenliste aus Knoten mit Tiefe im Eingabewert von N oder größer.

  • Eine Abfrage mit N Segmenten, N >= 0, die alle Kind-Segmente sind (Abschnitt 2.5.1), erzeugt eine Knotenliste aus Knoten genau der Tiefe N im Eingabewert.

Es gibt zwei Segmentarten: Kind-Segmente und Nachfahren-Segmente.

segment             = child-segment / descendant-segment

Syntax und Semantik jeder Segmentart sind unten definiert.

2.5.1. Child Segment (Kind-Segment)

2.5.1.1. Syntax

Das Kind-Segment besteht aus einer nicht leeren, kommagetrennten Sequenz von Selektoren in eckigen Klammern.

Kurzschreibweisen existieren auch, wenn genau ein Platzhalter- oder Name-Selektor vorkommt.

child-segment       = bracketed-selection /
("."
(wildcard-selector /
member-name-shorthand))

bracketed-selection = "[" S selector *(S "," S selector) S "]"

member-name-shorthand = name-first *name-char
name-first = ALPHA /
"_" /
%x80-D7FF /
; skip surrogate code points
%xE000-10FFFF
name-char = name-first / DIGIT
DIGIT               = %x30-39              ; 0-9
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z

., ein Kind-Segment direkt aus einem Platzhalter-Selektor gebaut, ist Kurzform für [].

.<member-name>, ein Kind-Segment aus member-name-shorthand gebaut, ist Kurzform für ['<member-name>']. Hinweis: Nur mit Mitgliedsnamen nutzbar, die aus den in der ABNF-Regel member-name-shorthand spezifizierten Zeichen bestehen. Beispielsweise ist $.foo.bar Kurzform für $['foo']['bar'] (nicht für $['foo.bar']).

2.5.1.2. Semantics (Semantik)

Ein Kind-Segment enthält eine Sequenz von Selektoren, von denen jeder null oder mehr Kinder des Eingabewerts auswählt.

Selektoren verschiedener Art können in einem einzigen Kind-Segment kombiniert werden.

Für jeden Knoten in der Eingabe-Knotenliste ist die resultierende Knotenliste eines Kind-Segments die Verkettung der Knotenlisten aus jedem Selektor in der Reihenfolge der Selektorliste. Hinweis: Ein mehrfach getroffener Knoten bleibt entsprechend oft in der Knotenliste.

Wo ein Selektor eine Knotenliste in mehr als einer möglichen Ordnung erzeugen kann, kann jedes Vorkommen des Selektors im Kind-Segment eine Knotenliste in unterschiedlicher Ordnung erzeugen.

Zusammengefasst: Ein Kind-Segment geht eine Ebene tiefer in die Struktur des Eingabewerts.

2.5.1.3. Examples (Beispiele)

JSON:

["a", "b", "c", "d", "e", "f", "g"]

Abfragen:

QueryResultResultComment
Paths
$[0,"a"$[0]Indizes
3]"d"$[3]
$[0:2,"a"$[0]Slice und
5]"b"$[1]Index
"f"$[5]
$[0,"a"$[0]Doppelte
0]"a"$[0]Einträge

Tabelle 15: Beispiele Kind-Segment

2.5.2. Descendant Segment (Nachfahren-Segment)

2.5.2.1. Syntax

Das Nachfahren-Segment besteht aus zwei Punkten .. gefolgt von einem Kind-Segment (Klammernotation).

Kurzschreibweisen entsprechen den Kurzformen des Kind-Segments.

descendant-segment  = ".." (bracketed-selection /
wildcard-selector /
member-name-shorthand)

.., das Nachfahren-Segment direkt aus einem Platzhalter-Selektor gebaut, ist Kurzform für ..[].

..<member-name>, ein Nachfahren-Segment aus member-name-shorthand gebaut, ist Kurzform für ..['<member-name>']. Hinweis: Wie bei der ähnlichen Kurzform eines Kind-Segments nur mit bestimmten Zeichen im Mitgliedsnamen gemäß member-name-shorthand.

Hinweis: Allein .. ist kein gültiges Segment.

2.5.2.2. Semantics (Semantik)

Ein Nachfahren-Segment erzeugt null oder mehr Nachfahren eines Eingabewerts.

Für jeden Knoten in der Eingabe-Knotenliste besucht ein Nachfahren-Selektor den Eingabeknoten und jeden seiner Nachfahren derart, dass:

  • Knoten beliebiger Arrays in Array-Reihenfolge besucht werden, und

  • Knoten vor ihren Nachfahren besucht werden.

Die Reihenfolge der Kinder eines Objekts ist nicht vorgegeben, da JSON-Objekte ungeordnet sind.

Angenommen, das Nachfahren-Segment hat die Form ..[<selectors>] (nach Umwandlung jeder Kurzform in Klammernotation), und die besuchten Knoten in Besuchsreihenfolge sind D1, ..., Dn (n >= 1). Hinweis: D1 ist der Eingabewert.

Für jedes i mit 1 <= i <= n sei Ri ein Ergebnis der Anwendung des Kind-Segments [<selectors>] auf den Knoten Di.

Für jeden Knoten in der Eingabe-Knotenliste ist das Ergebnis des Nachfahren-Segments die Verkettung von R1, ..., Rn (in dieser Reihenfolge). Diese Ergebnisse werden dann in Eingabe-Knotenlisten-Reihenfolge verkettet zum Segmentergebnis.

Zusammengefasst: Ein Nachfahren-Segment geht eine oder mehr Ebenen tiefer in die Struktur jedes Eingabewerts.

2.5.2.3. Examples (Beispiele)

JSON:

{
"o": {"j": 1, "k": 2},
"a": [5, 3, [{"j": 4}, {"k": 6}]]
}

Abfragen:

(Beachten Sie, dass das vierte Beispiel in zwei äquivalenten Abfragen ausgedrückt werden kann, in Tabelle 16 in einer Tabellenzeile statt zwei fast identischer Zeilen.)

QueryResultResult PathsComment
$..j1$['o']['j']Objektwerte
4$['a'][2][0]['j']
$..j4$['a'][2][0]['j']Alternatives
1$['o']['j']Ergebnis
$..[0]5$['a'][0]Arraywerte
{"j": 4}$['a'][2][0]
$..[*]{"j": 1,$['o']Alle Werte
oder"k": 2}$['a']
$..*[5, 3,$['o']['j']
[{"j": 4},$['o']['k']
{"k": 6}]]$['a'][0]
1$['a'][1]
2$['a'][2]
5$['a'][2][0]
3$['a'][2][1]
[{"j": 4},$['a'][2][0]['j']
{"k": 6}]$['a'][2][1]['k']
{"j": 4}
{"k": 6}
4
6
$..o{"j": 1,$['o']Eingabewert wird
"k": 2}besucht
$.o..[*,1$['o']['j']Nicht-deterministische
*]2$['o']['k']Ordnung
2$['o']['k']
1$['o']['j']
$.a..[0,5$['a'][0]Mehrere Segmente
1]3$['a'][1]
{"j": 4}$['a'][2][0]
{"k": 6}$['a'][2][1]

Tabelle 16: Beispiele Nachfahren-Segment

Hinweis: Die Ordnung der Ergebnisse für die $..[]- und $..-Beispiele oben ist nicht garantiert, außer dass:

  • {"j": 1, "k": 2} vor 1 und 2 erscheinen muss,

  • [5, 3, [{"j": 4}, {"k": 6}]] vor 5, 3 und [{"j": 4}, {"k": 6}] erscheinen muss,

  • 5 vor 3 erscheinen muss, das vor [{"j": 4}, {"k": 6}] erscheinen muss,

  • 5 und 3 vor {"j": 4}, 4, {"k": 6} und 6 erscheinen müssen,

  • [{"j": 4}, {"k": 6}] vor {"j": 4} und {"k": 6} erscheinen muss,

  • {"j": 4} vor {"k": 6} erscheinen muss,

  • {"k": 6} vor 4 erscheinen muss, und

  • 4 vor 6 erscheinen muss.

Das Beispiel oben mit der Abfrage $.o..[*, *] zeigt, dass ein Selektor bei jedem Auftreten im Nachfahren-Segment Knotenlisten in unterschiedlicher Ordnung erzeugen kann.

Das Beispiel oben mit der Abfrage $.a..[0, 1] zeigt, dass das Kind-Segment [0, 1] nacheinander auf jeden Knoten angewendet wird (statt die Knoten einmal pro Selektor zu besuchen, wie bei einigen nicht konformen JSONPath-Implementierungen).