> ## Documentation Index
> Fetch the complete documentation index at: https://dokumentation.websale.de/llms.txt
> Use this file to discover all available pages before exploring further.

# Beispiele zur JSON-Schnittstelle

> Fünf durchgerechnete Fälle für die JSON-Schnittstelle, von Crosslinks über verschränkte Dateien bis zur Nutzlast für ein serverseitiges Ereignis.

Die JSON-Schnittstelle holt Daten aus Dateien in das Template, die nicht aus der Warenwirtschaft stammen. Wie sie eingerichtet wird und was die `EJD-`-Tags im Einzelnen können, steht in der Referenz. Diese Seite zeigt, wie sie in konkreten Aufgaben zusammenspielen.

Wegweiser: [JSON-Schnittstelle](https://dokumentation.websale.de/v8s/externe-dienste/json-schnittstelle.md) · Referenz: [EJD- (JSON-Daten)](https://dokumentation.websale.de/v8s/externe-dienste/json-schnittstelle.md#die-beiden-tag-familien)

Alle Beispiele folgen demselben Dreischritt: Datei laden und mit einer Kennung versehen, prüfen ob das geklappt hat, dann über den Zugriffspfad auf die Werte zugreifen.

## Crosslinks zu einem Produkt

Zu jedem Produkt gehört eine Datei mit Querverweisen, wahlweise auf einzelne Produkte oder auf eine Gruppe, jeweils mit eigener Überschrift.

Die Datei heißt nach der Produktnummer und liegt global:

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
   "headline": "Passend dazu",
   "description": "Diese Beschreibung darf HTML enthalten.",
   "crosslinkProducts": [
      {
         "productID": "12345",
         "section": { "title": "Oft zusammen gekauft", "description": "…" }
      },
      {
         "productGroup": "RNA1,RNA2,TNA1,TNA2",
         "section": { "title": "Zubehör", "description": "…" }
      }
   ]
}
```

Im Template der Produktdetailansicht:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(global,crosslink-$PR-Number$.json,cross)~

{EJD-DataOK(cross)}
   ~EJD-SetUseID(cross)~

   ~EJD-DA-Value(headline)~
   ~EJD-DA-Value(description)~

   ~EJD-DA-TouchArrayElements(crosslinkProducts)~
   ~DC-ZeroLoop1_set($EJD-LastValueAccessed$)~

   {@DC-ZeroLoop1}
      ~EJD-DA-Value(crosslinkProducts[$DC-ZeroLoop1_position$].section.title)~
      ~EJD-DA-Value(crosslinkProducts[$DC-ZeroLoop1_position$].section.description)~

      {!EJD-DA-NameExists(crosslinkProducts[$DC-ZeroLoop1_position$].productGroup)}
         ~EJD-DA-TouchValue(crosslinkProducts[$DC-ZeroLoop1_position$].productID)~
         ~DC-FPcrossNumber_set($EJD-LastValueAccessed$)~
         {PR-LoadData($DC-FPcrossNumber$,1)}
            <img src="~PR-MiniThumbnail~" alt="~PR-Name_StripHtml~">
            ~PR-Name~ ~PR-Price~ ~WS-CurrencySymbol~
         {/PR-LoadData($DC-FPcrossNumber$,1)}
      {/!EJD-DA-NameExists(crosslinkProducts[$DC-ZeroLoop1_position$].productGroup)}

      {EJD-DA-NameExists(crosslinkProducts[$DC-ZeroLoop1_position$].productGroup)}
         ~EJD-DA-TouchValue(crosslinkProducts[$DC-ZeroLoop1_position$].productGroup)~
         ~DC-DynamicLoop1_set($EJD-LastValueAccessed$)~
         {DC-DynamicLoop1}
            {@DC-DynamicLoop1}
               {PR-LoadData($DC-DynamicLoop1_data$,1)}
                  <img src="~PR-MiniThumbnail~" alt="~PR-Name_StripHtml~">
                  ~PR-Name~ ~PR-Price~ ~WS-CurrencySymbol~
               {/PR-LoadData($DC-DynamicLoop1_data$,1)}
            {/@DC-DynamicLoop1}
         {/DC-DynamicLoop1}
      {/EJD-DA-NameExists(crosslinkProducts[$DC-ZeroLoop1_position$].productGroup)}
   {/@DC-ZeroLoop1}
{/EJD-DataOK(cross)}
```

| Baustein | Aufgabe |
| - | - |
| `EJD-SetUseID()` | setzt die Kennung als Standard, danach entfällt sie in jedem weiteren Tag |
| `EJD-DA-TouchArrayElements()` | legt die Anzahl der Elemente in `EJD-LastValueAccessed` ab |
| `DC-ZeroLoop1` | zählt von 0 an, passend zu den Positionen im JSON-Array |
| `EJD-DA-NameExists()` | unterscheidet die beiden Fälle, Einzelprodukt oder Gruppe |
| `DC-DynamicLoop1` | zerlegt die kommaseparierte Liste der Gruppe in einzelne Nummern |

`DC-ZeroLoop` zählt ab 0, die gewöhnliche Schleife ab 1. Für Zugriffe in ein JSON-Array ist deshalb `DC-ZeroLoop` die richtige Wahl, denn `crosslinkProducts[0]` ist das erste Element.

> [!WARNING]
>
> Der Umweg über `TouchValue` und einen freien Parameter sieht umständlich aus, ist aber nötig. `EJD-DA-Value()` gibt einen Wert **aus**, es setzt ihn nicht als Argument in ein anderes Tag ein. `EJD-DA-TouchValue()` legt den Wert deshalb in `EJD-LastValueAccessed` ab, von wo ihn ein anderes Tag abholen kann.
>
> Das zweite Argument von `PR-LoadData()` entscheidet, wie das erste gelesen wird: `0` als Produktindex, `1` als Produktnummer. Das Feld im Beispiel heißt `productID` und enthält eine Produktnummer, deshalb steht hier `1`. Prüfen Sie, welche der beiden Angaben in Ihren JSON-Dateien steht.

Referenz: [EJD-LoadData()](https://dokumentation.websale.de/v8s/referenz/tags/ejd.md#die-tags-im-uberblick) · [EJD-SetUseID()](https://dokumentation.websale.de/v8s/referenz/tags/ejd.md#die-tags-im-uberblick) · [EJD-DA-TouchArrayElements()](https://dokumentation.websale.de/v8s/referenz/tags/ejd.md#die-tags-im-uberblick) · [EJD-DA-NameExists()](https://dokumentation.websale.de/v8s/referenz/tags/ejd.md#die-tags-im-uberblick) · [DC-ZeroLoopX](https://dokumentation.websale.de/v8s/referenz/tags/dc/schleifen.md) · DC-DynamicLoopX · [PR-LoadData()](https://dokumentation.websale.de/v8s/referenz/tags/pr/grundlagen-und-produktdaten.md#die-tags-im-uberblick)

## Zwei Dateien verschränkt lesen

Eine Datei enthält die sprachabhängigen Beschriftungen, eine zweite die Bilddaten eines Produkts. Beide werden gleichzeitig geladen und bekommen eigene Kennungen.

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{ "MainPicture": "Detailansicht", "SmallImages": "weitere Ansichten" }
```

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{
   "MainPicture": "img/12345.jpg",
   "Images": [
      { "Descr": "Ansicht vorne",  "URL": "img/12345-1.jpg" },
      { "Descr": "Ansicht oben",   "URL": "img/12345-2.jpg" }
   ]
}
```

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(subshop,img_captions_productpage.json,cap)~
~EJD-LoadData(subshop,$PR-Number$.json,data)~

{EJD-DA-NameExists(MainPicture,data)}
   ~EJD-DA-Value(MainPicture,cap)~:
   <img src="~EJD-DA-Value(MainPicture,data)~" alt="">
{/EJD-DA-NameExists(MainPicture,data)}

~EJD-DA-TouchArrayElements(Images,data)~
{DC-CompareDigitGT($EJD-LastValueAccessed$,0)}
   ~DC-ZeroLoop1_set($EJD-LastValueAccessed$)~

   ~EJD-DA-Value(SmallImages,cap)~:

   {@DC-ZeroLoop1}
      <img src="~EJD-DA-Value(Images[$DC-ZeroLoop1_position$].URL,data)~"
           alt="~EJD-DA-Value(Images[$DC-ZeroLoop1_position$].Descr,data)~">
   {/@DC-ZeroLoop1}
{/DC-CompareDigitGT($EJD-LastValueAccessed$,0)}
```

Weil beide Dateien einen Eintrag `MainPicture` haben, muss hier bei jedem Zugriff die Kennung mitstehen. `EJD-SetUseID()` wäre an dieser Stelle gerade falsch, es würde die Unterscheidung aufheben.

Die Schleife wird gesetzt, **bevor** die Überschrift ausgegeben wird, und die Überschrift steht innerhalb der Prüfung auf mehr als null Elemente. So erscheint keine Überschrift über einer leeren Liste.

> [!WARNING]
>
> Die Pfade in `URL` zeigen auf das Templateverzeichnis des Shops, nicht auf den FTP-Zugang der JSON-Schnittstelle. Die Schnittstelle liefert die Daten, die Bilder liegen weiterhin dort, wo die übrigen Bilder des Shops liegen.

Die Beschreibung aus der Datei gehört in das `alt`-Attribut und nicht als Text unter das Bild, wie es die bisherige Beschreibung zeigt. Dann hat das Bild einen Namen, und der Text erscheint nicht doppelt.

## Eine unbekannte Datei durchlaufen

Ist der Aufbau der Datei nicht im Voraus bekannt, läuft `EJD-ElementIterator` über die vorhandenen Elemente.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(global,test.json,jdat)~

{EJD-DataOK(jdat)}
   ~EJD-SetUseID(jdat)~

   {@EJD-ElementIterator()}
      ~EJD-ElementIterator~ : ~EJD-DA-Value($EJD-ElementIterator$)~

      {EJD-DA-IsObject($EJD-ElementIterator$)}
         ~DC-FP1_set($EJD-ElementIterator$)~
         {@EJD-ElementIterator($DC-FP1$)}
            ~EJD-ElementIterator~ : ~EJD-DA-Value($DC-FP1$.$EJD-ElementIterator$)~
         {/@EJD-ElementIterator($DC-FP1$)}
      {/EJD-DA-IsObject($EJD-ElementIterator$)}
   {/@EJD-ElementIterator()}
{/EJD-DataOK(jdat)}
```

Der Name des aktuellen Elements steht in `EJD-ElementIterator` selbst. Für die zweite Ebene muss er vorher in einen freien Parameter gelegt werden, weil die innere Schleife das Tag mit ihrem eigenen Namen überschreibt.

> [!WARNING]
>
> Das Beispiel geht nur eine Ebene tief und behandelt nur Objekte. Ein Array meldet sich mit dem Typ `array` und bleibt uneröffnet. Für Arrays brauchen Sie zusätzlich `EJD-DA-TouchArrayElements()` und eine Zählschleife, wie im ersten Beispiel.

Referenz: [EJD-ElementIterator](https://dokumentation.websale.de/v8s/referenz/tags/ejd.md#die-tags-im-uberblick) · [EJD-DA-IsObject()](https://dokumentation.websale.de/v8s/referenz/tags/ejd.md#die-tags-im-uberblick)

## Die technische Antwort eines Zahlungsdienstleisters lesen

Der Typ `intern` greift auf Daten zu, die der Shop selbst abgelegt hat, hier die Antwort des Zahlungsdienstleisters.

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~EJD-LoadData(intern,PaymorrowGetPaymentTokenResponse,paym_get)~

{EJD-DataOK(paym_get)}
   ~EJD-DA-Value(getPaymentTokenResponse.responseId,paym_get)~
{/EJD-DataOK(paym_get)}

{!EJD-DataOK(paym_get)}
   Die technische Antwort konnte nicht gelesen werden. Fehlercode: ~EJD-DataOK(paym_get)~
{/!EJD-DataOK(paym_get)}
```

`EJD-DataOK()` arbeitet als Klammerung und als Einzeltag. Als Klammerung greift es, wenn die Daten da sind. Als Einzeltag gibt es den Fehlercode aus, deshalb steht es im negativen Zweig noch einmal.

> [!WARNING]
>
> Die Antworten der Dienstleister sind für die Fehlersuche gedacht. Geben Sie daraus nichts auf einer Seite aus, die der Käufer sieht. Technische Kennungen und Fehlercodes gehören in das Protokoll, nicht in den Bestellablauf.

## Nutzlast für ein serverseitiges Ereignis

Für `ASSE-Fire()` wird ein JSON-Objekt gebraucht. Dafür gibt es zwei Wege.

**Von Hand zusammengesetzt**, mit einem freien Parameter:

```html theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
~DC-FPjsonResult_set({"data":[{)~
~DC-FPjsonResult_append("event_name": "ViewContent")~

{CAT-Data}
   ~DC-FPjsonResult_append(,"contents": [)~
   ~DC-Int3_set(0)~
   {@PR-Data}
      ~DC-Int3_inc~
      {!DC-Int3(1)}~DC-FPjsonResult_append(,)~{/!DC-Int3(1)}
      ~DC-FPjsonResult_append({)~
      ~DC-FPjsonResult_append("id": "$PR-ProdIndex$")~
      ~WS-DisablePriceAndNumberFormat~
      ~DC-FPjsonResult_append(,"item_price": $PR-Price$)~
      ~WS-EnablePriceAndNumberFormat~
      ~DC-FPjsonResult_append(})~
   {/@PR-Data}
   ~DC-FPjsonResult_append(])~
{/CAT-Data}

~DC-FPjsonResult_append(}]})~

~ASSE-Fire(<ID>,$DC-FPjsonResult$)~
```

**Mit den JSON-Tags** entsteht dasselbe Ergebnis, ohne eine einzige Klammer von Hand. Das Beispiel dazu steht in der Referenz unter "Ein Beispiel aus dem Tracking".

Referenz: [EJD- (JSON-Daten)](https://dokumentation.websale.de/v8s/referenz/tags/ejd.md) · Wegweiser: [Asynchronous Server Side Events](https://dokumentation.websale.de/v8s/schnittstellen/marketing-seo-und-portale/ws-asse.md)

Beide Wege erzeugen:

```json theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/websale.json"]}}
{ "data": [
   { "event_name": "ViewContent",
     "contents": [
        { "id": "20002", "item_price": 37.95 },
        { "id": "72727", "item_price": 59.95 }
     ]
   }
] }
```

> [!WARNING]
>
> **Nehmen Sie den Weg über die JSON-Tags.**
>
> Dass der Shop die Klammern setzt, ist dabei der kleinere Vorteil. Der größere: Er maskiert auch die Werte. Enthält ein Produktname ein Anführungszeichen oder einen Rückwärtsschrägstrich, entsteht beim Zusammensetzen von Hand ungültiges JSON, und der Empfänger verwirft die ganze Übertragung. Bemerken würden Sie das erst, wenn die Zahlen im Zielsystem fehlen.
>
> Der Weg von Hand bleibt nachvollziehbar, solange nur Zahlen und Produktindizes übertragen werden. Sobald Texte dazukommen, ist er ein Risiko.

`~WS-DisablePriceAndNumberFormat~` vor dem Preis ist in beiden Varianten unverzichtbar. Ohne diese Zeile wird der Preis mit Tausendertrennzeichen und Komma eingesetzt, und das Zielsystem liest daraus eine falsche Zahl oder bricht ab.

Referenz: [DC-FPX\_append](https://dokumentation.websale.de/v8s/referenz/tags/dc/parameter.md#die-tags-im-uberblick) · [ASSE-Fire()](https://dokumentation.websale.de/v8s/referenz/tags/asse.md#asse-fire) · [WS-DisablePriceAndNumberFormat](https://dokumentation.websale.de/v8s/referenz/tags/ws/shop-seite-und-technik.md#die-tags-im-uberblick)

## Verwandte Themen

* Wegweiser: [JSON-Schnittstelle](https://dokumentation.websale.de/v8s/externe-dienste/json-schnittstelle.md)
* Wegweiser: Integration eines CMS
* Wegweiser: Asynchronous Server Side Events
* Referenz: [EJD- (JSON-Daten)](https://dokumentation.websale.de/v8s/referenz/tags/ejd.md)


## Related topics

- [Beispiele für Asynchronous Server Side Events](https://dokumentation.websale.de/v8s/anwendungsbeispiele/appex-asse-beispiele.md)
- [Anwendungsbeispiele](https://dokumentation.websale.de/v8s/anwendungsbeispiele/anwendungsbeispiele.md)
- [JSON-Schnittstelle](https://dokumentation.websale.de/v8s/externe-dienste/json-schnittstelle.md)
- [EJD- (JSON-Schnittstelle)](https://dokumentation.websale.de/v8s/referenz/tags/ejd.md)
- [PPP- (PayPal PLUS)](https://dokumentation.websale.de/v8s/referenz/tags/ppp-paypal-plus.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.