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:
| Query | Result | Result | Comment |
|---|---|---|---|
| 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.)
| Query | Result | Result Paths | Comment |
|---|---|---|---|
| $..j | 1 | $['o']['j'] | Objektwerte |
| 4 | $['a'][2][0]['j'] | ||
| $..j | 4 | $['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).