Block 06 · Schnittstellen & Datenformate

Immer 8/9 Prüfungen · Ø 15 von 200 Punkten · fast ausschließlich Teil 1 (8×) · Trend ↑ bei REST/HTTP · Lösungen: 06_Schnittstellen_Datenformate_Loesungen.html
So arbeitest du mit diesem Block Erst den Erklärungssatz lesen, dann die Aufgaben mit dem Belegsatz daneben lösen (Belegsatz am besten separat ausdrucken und neben die Aufgaben legen). Zeitrichtwert: 1 Punkt ≈ 0,9 Minuten. Lösungen erst danach in der separaten Lösungsdatei nachsehen. Zu den Code- und Validierungsaufgaben gibt es dort Pseudocode bzw. Musterlösungen und lauffähige Java-Dateien im Ordner java\06_Schnittstellen_Datenformate\ (nur JDK, keine Bibliotheken).

A · Erklärungssatz

Schnittstellen und Datenformate kamen in 8 von 9 Prüfungen vor, fast immer in Teil 1 als eine Teilaufgabe von 6 bis 25 Punkten. Die Fragen sind meist Wissens- und Verständnisfragen („Erläutern Sie …“, „Beschreiben Sie die Parameter …“), dazu kommen Anwendungsaufgaben: XML-Fehler anhand einer DTD finden, Tabellen in JSON überführen, eine HTTP-Antwort im Code zusammenbauen. Einen Belegsatz mit Notationshilfen gibt es für diesen Block nicht – Syntax und Begriffe musst du selbst können.

UnterthemaKategorieTypische PunkteWichtigste Fähigkeit
SD-01 XMLMeistens (JSON/XML)6–13wohlgeformt vs. gültig, Fehler anhand einer DTD finden, Grenzen der Schema-Validierung
SD-02 JSONMeistens (JSON/XML)7–14Tabellen fehlerfrei in JSON überführen, Embedding vs. Referenz, JSON im Code erzeugen
SD-03 REST & HTTP-MethodenOft ↑ (REST/HTTP)2–12REST-Konzept erläutern, CRUD ↔ HTTP-Methoden, Endpunkte entwerfen
SD-04 HTTP-Request/ResponseOft ↑ (REST/HTTP)2–10Aufbau von Request und Response, Statuscodes, URL-Parameter, Antwort im Code bauen
SD-05 eRechnungSonstige ⚠ca. 18 (W25)Ziel, Formate, Pflichten, Validierung, Datenschutz – oft mit englischem Text

Punkte des Blocks je Prüfung: W21 2 · S22 – · W22 13 · S23 13 · W23 14 · S24 25 · W24 18 · W25 24 · S26 12.

SD-01 · XML Meistens

Vorkommen: JSON/XML zusammen 6/9 (W22, S23, W23, S24, W24, W25) · XML konkret: W22 T1 A3c (13 P: Zweck der DTD, wohlgeformt/gültig, Fehler finden), W25 T1 A3bc (6 P: warum Schema-Validierung nicht reicht); eRechnungen (W25) sind XML-Dokumente

Was ist XML?

XML (Extensible Markup Language) ist eine textbasierte Auszeichnungssprache für hierarchisch strukturierte Daten. Sie ist für Menschen und Maschinen lesbar, plattform- und programmiersprachenunabhängig und wird vor allem für den Datenaustausch zwischen Systemen verwendet (eRechnung, Behördenstandards, SOAP-Webservices, Konfigurationsdateien, Office-Dateiformate). Anders als HTML gibt XML keine Elementnamen vor („extensible“): Die Namen legt man selbst fest. Welche Elemente in welcher Reihenfolge erlaubt sind, beschreibt eine DTD oder ein XML-Schema (XSD).

Aufbau eines XML-Dokuments

Beispiel: Spielplan eines Stadttheaters (die Zeilennummern gehören nicht zum Dokument).

 1  <?xml version="1.0" encoding="UTF-8"?>
 2  <!DOCTYPE spielplan SYSTEM "spielplan.dtd">
 3  <!-- Spielplan des Stadttheaters (Auszug) -->
 4  <spielplan saison="2026/27">
 5    <vorstellung id="v1" saal="gross">
 6      <stueck>Der Besuch der alten Dame</stueck>
 7      <datum>2026-11-14</datum>
 8      <preis>32.00</preis>
 9    </vorstellung>
10    <vorstellung id="v2" saal="studio" ausverkauft="ja">
11      <stueck>Momo</stueck>
12      <datum>2026-11-15</datum>
13      <preis>12.50</preis>
14      <hinweis>ab 8 Jahren</hinweis>
15      <hinweis>Einführung 19:15 Uhr</hinweis>
16    </vorstellung>
17  </spielplan>
BestandteilBeispiel (Zeile)Erklärung
Prolog / XML-Deklaration<?xml version="1.0" encoding="UTF-8"?> (1)nennt XML-Version und Zeichenkodierung; optional, muss aber – wenn vorhanden – ganz am Anfang stehen
Dokumenttyp-Deklaration<!DOCTYPE spielplan SYSTEM "spielplan.dtd"> (2)verweist auf die DTD, gegen die geprüft wird; der Name muss dem Wurzelelement entsprechen
Kommentar<!-- … --> (3)wird vom Parser ignoriert
Wurzelelement<spielplan> … </spielplan> (4–17)genau ein Element umschließt alle anderen
Element<stueck>Momo</stueck> (11)Start-Tag, Inhalt, End-Tag; Inhalt = Text und/oder Kindelemente
leeres Element<pause/>Kurzform für <pause></pause>
Attributsaal="studio" (10)Name-Wert-Paar im Start-Tag; Wert immer in Anführungszeichen; jeder Attributname höchstens einmal je Element
Textinhalt32.00 (8)ohne Schema ist alles Text – „32.00“ ist für den Parser eine Zeichenkette
Entität&lt; &gt; &amp; &quot; &apos;Ersatz für Sonderzeichen, z. B. Hansen &amp; Söhne
spielplan @saison="2026/27" vorstellung @id="v1" @saal="gross" vorstellung @id="v2" @saal="studio" @ausverkauft="ja" stueck datum preis stueck datum preis hinweis (2×) „Der Besuch …“ „2026-11-14“ „32.00“ „Momo“ „2026-11-15“ „12.50“ „ab 8 Jahren“ „Einführung …“ = Element @name = Attribut (gehört zum Element, ist kein Kindknoten) „…“ = Textinhalt (Blatt)
Abb. A-1: Das Dokument als Baum – ein Wurzelelement, Kindelemente, Attribute und Textinhalte

Element oder Attribut? Faustregel: Attribute für Kennungen und kurze Metadaten (id, saal, einheit), Elemente für die eigentlichen Daten – und immer dann, wenn ein Wert mehrfach vorkommen oder selbst Struktur haben kann (Attribute sind nicht wiederholbar und nicht verschachtelbar).

Namensräume (namespaces) verhindern Namenskonflikte, wenn Elemente aus verschiedenen Vokabularen in einem Dokument zusammenkommen. Ein Namensraum wird durch eine eindeutige URI bezeichnet (sie muss nicht abrufbar sein) und entweder als Standardnamensraum (xmlns="…") oder mit Präfix (xmlns:cbc="…", Elemente dann <cbc:ID>) deklariert. eRechnungen im UBL-Format nutzen z. B. die Präfixe cbc und cac (Beispiel in SD-05).

Wohlgeformt und gültig

Merke Wohlgeformt (well-formed) = das Dokument hält die Syntaxregeln von XML ein. Das prüft jeder XML-Parser, auch ohne DTD.
Gültig (valid) = das Dokument ist wohlgeformt und entspricht zusätzlich einer vorgegebenen Grammatik (DTD oder XSD): nur erlaubte Elemente und Attribute, richtige Reihenfolge und Anzahl, Pflichtangaben vorhanden.
Jedes gültige Dokument ist wohlgeformt – aber nicht umgekehrt.

Regeln der Wohlgeformtheit (Syntax)

  1. genau ein Wurzelelement
  2. zu jedem Start-Tag ein passendes End-Tag (oder leeres Element <x/>)
  3. korrekt verschachtelt: <a><b></b></a>, nicht <a><b></a></b>
  4. Groß-/Kleinschreibung zählt: <Preis> ≠ <preis>
  5. Attributwerte in Anführungszeichen, kein Attributname doppelt im selben Element
  6. < und & im Text nur als Entität
  7. Namen beginnen mit Buchstabe oder _, keine Leerzeichen
  8. XML-Deklaration (falls vorhanden) ganz am Anfang

Zusätzlich für die Gültigkeit (gegen DTD/XSD)

  1. nur deklarierte Elemente und Attribute
  2. Kindelemente in der vorgegebenen Reihenfolge und Anzahl
  3. Pflichtattribute vorhanden, Attributwerte aus der erlaubten Liste
  4. Werte vom Typ ID im ganzen Dokument eindeutig
  5. Wurzelelement wie in der DOCTYPE-Deklaration
  6. nur bei XSD: Datentypen und Wertebereiche (z. B. Datum, Zahl ≥ 0)
alle Textdateien (z. B. mit Endung .xml) wohlgeformte XML-Dokumente (Syntaxregeln eingehalten) gültige XML-Dokumente wohlgeformt UND passend zu einer DTD bzw. XSD gültig ⇒ wohlgeformt, aber nicht umgekehrt
Abb. A-2: Gültige Dokumente sind eine Teilmenge der wohlgeformten Dokumente
Typische Fallen

DTD (Document Type Definition)

Die DTD ist die Grammatik (der Bauplan) eines Dokumenttyps: Sie legt fest, welche Elemente und Attribute vorkommen dürfen, in welcher Reihenfolge und wie oft. Wofür? Damit Sender und Empfänger eine gemeinsame, verbindliche Struktur haben (Schnittstellenvertrag) und eingehende Dokumente automatisch geprüft (validiert) werden können, bevor sie verarbeitet werden. Die DTD kann im Dokument stehen (interne DTD in <!DOCTYPE spielplan [ … ]>) oder – wie oben – in einer externen Datei, auf die die DOCTYPE-Deklaration mit SYSTEM "datei.dtd" verweist; so können viele Dokumente dieselbe DTD nutzen.

 1  <!ELEMENT spielplan (vorstellung+)>
 2  <!ATTLIST spielplan saison CDATA #REQUIRED>
 3  <!ELEMENT vorstellung (stueck, datum, preis, hinweis*)>
 4  <!ATTLIST vorstellung id          ID             #REQUIRED
 5                        saal        (gross|studio) "gross"
 6                        ausverkauft (ja|nein)      #IMPLIED>
 7  <!ELEMENT stueck  (#PCDATA)>
 8  <!ELEMENT datum   (#PCDATA)>
 9  <!ELEMENT preis   (#PCDATA)>
10  <!ELEMENT hinweis (#PCDATA)>
Elementdeklaration <!ELEMENT name (inhalt)>
SchreibweiseBedeutung
(a, b, c)Sequenz: genau in dieser Reihenfolge
(a | b)Auswahl: entweder a oder b
agenau einmal (1)
a?optional, höchstens einmal (0..1)
a*beliebig oft, auch keinmal (0..n)
a+mindestens einmal (1..n)
(#PCDATA)nur Text (parsed character data)
EMPTY / ANYleeres Element / beliebiger Inhalt
Attributdeklaration <!ATTLIST element name typ vorgabe>
TeilMöglichkeiten
TypCDATA beliebiger Text
ID im Dokument eindeutig (Wert beginnt mit Buchstabe)
IDREF verweist auf eine ID
(w1|w2|w3) Aufzählung erlaubter Werte
Vorgabe#REQUIRED Pflichtattribut
#IMPLIED optional, ohne Standardwert
"wert" Standardwert, wenn das Attribut fehlt
#FIXED "wert" fester Wert

Kardinalitäten gelten auch für Gruppen: (telefon | email)+ heißt „mindestens ein Kontakt, jeweils Telefon oder E-Mail“. Lies die DTD aus Zeile 3 so: Eine Vorstellung besteht aus genau einem Stück, dann genau einem Datum, dann genau einem Preis, danach beliebig vielen Hinweisen – genau in dieser Reihenfolge.

So gehst du vor: Fehler in einem XML-Dokument anhand der DTD finden

  1. DTD in Worte fassen: Für jedes Element notieren, welche Kinder in welcher Reihenfolge und Anzahl erlaubt sind; für jedes Attribut: Pflicht? erlaubte Werte? ID?
  2. Erster Durchgang – Wohlgeformtheit, Zeile für Zeile: passt jedes End-Tag exakt (auch Groß-/Kleinschreibung, Schrägstrich)? Ist alles korrekt verschachtelt und geschlossen? Stehen alle Attributwerte in Anführungszeichen?
  3. Zweiter Durchgang – Gültigkeit: Ist jedes Element und Attribut deklariert? Stimmen Reihenfolge und Anzahl der Kinder? Fehlen Pflichtelemente oder Pflichtattribute? Sind Aufzählungswerte erlaubt? Kommt ein ID-Wert doppelt vor?
  4. Antwort je Fehler: Zeile, kurze Beschreibung („End-Tag passt nicht zum Start-Tag“), verletzte Eigenschaft (Wohlgeformtheit oder Gültigkeit).

Beispiel: Auszug mit Fehlern, geprüft gegen die Spielplan-DTD von oben.

 1  <?xml version="1.0" encoding="UTF-8"?>
 2  <!DOCTYPE spielplan SYSTEM "spielplan.dtd">
 3  <spielplan saison="2026/27">
 4    <vorstellung id="v3" saal="foyer">
 5      <datum>2026-11-20</datum>
 6      <stueck>Faust</stueck>
 7      <preis>18.00</preis>
 8    </vorstellung>
 9    <vorstellung id="v3">
10      <stueck>Woyzeck</Stueck>
11      <datum>2026-11-21</datum>
12      <preis>21.00</preis>
13    </vorstellung>
14  </spielplan>
ZeileBeschreibungEigenschaft
4saal="foyer" ist kein erlaubter Wert der Aufzählung (gross|studio)Gültigkeit
5–6datum steht vor stueck; die DTD verlangt (stueck, datum, preis, hinweis*)Gültigkeit
9id="v3" ist bereits in Zeile 4 vergeben; Werte vom Typ ID müssen eindeutig seinGültigkeit
10End-Tag </Stueck> passt nicht zum Start-Tag <stueck> (Groß-/Kleinschreibung)Wohlgeformtheit

XML-Schema (XSD)

Ein XML-Schema (XML Schema Definition, Dateiendung .xsd) erfüllt denselben Zweck wie eine DTD, ist aber selbst ein XML-Dokument und deutlich mächtiger: Es kennt Datentypen, Wertebereiche, genaue Mindest- und Höchstanzahlen und Namensräume. eRechnungen (UBL, CII) werden mit XSD-Dateien beschrieben. Dasselbe Spielplan-Format als XSD:

 1  <?xml version="1.0" encoding="UTF-8"?>
 2  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 3    <xs:element name="spielplan">
 4      <xs:complexType>
 5        <xs:sequence>
 6          <xs:element ref="vorstellung" maxOccurs="unbounded"/>
 7        </xs:sequence>
 8        <xs:attribute name="saison" type="xs:string" use="required"/>
 9      </xs:complexType>
10    </xs:element>
11    <xs:element name="vorstellung">
12      <xs:complexType>
13        <xs:sequence>
14          <xs:element name="stueck"  type="xs:string"/>
15          <xs:element name="datum"   type="xs:date"/>
16          <xs:element name="preis"   type="betrag"/>
17          <xs:element name="hinweis" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
18        </xs:sequence>
19        <xs:attribute name="id"          type="xs:ID"      use="required"/>
20        <xs:attribute name="saal"        type="xs:string"  default="gross"/>
21        <xs:attribute name="ausverkauft" type="xs:string"/>
22      </xs:complexType>
23    </xs:element>
24    <xs:simpleType name="betrag">
25      <xs:restriction base="xs:decimal">
26        <xs:minInclusive value="0"/>
27        <xs:fractionDigits value="2"/>
28      </xs:restriction>
29    </xs:simpleType>
30  </xs:schema>
XSDBedeutungDTD
<xs:element name="x" type="xs:string"/>Element mit Datentyp(#PCDATA)
xs:string, xs:integer, xs:decimal, xs:boolean, xs:date, xs:dateTimeeingebaute Datentypen (xs:date = JJJJ-MM-TT, xs:decimal mit Dezimalpunkt)– (alles Text)
ohne AngabeminOccurs = maxOccurs = 1, also genau einmala
minOccurs="0"optionala?
minOccurs="0" maxOccurs="unbounded"beliebig ofta*
maxOccurs="unbounded"mindestens einmala+
minOccurs="2" maxOccurs="5"zwei bis fünf Malnicht möglich
<xs:sequence> / <xs:choice>feste Reihenfolge / Auswahl, / |
use="required"Pflichtattribut#REQUIRED
<xs:restriction> mit minInclusive, maxLength, pattern, enumerationeigener, eingeschränkter Datentyp (z. B. Betrag ≥ 0 mit 2 Nachkommastellen)nur Aufzählung bei Attributen
DTD und XSD im Vergleich
KriteriumDTDXSD
Schreibweiseeigene Syntaxselbst XML – mit XML-Werkzeugen bearbeit- und prüfbar
Datentypenkeine, alles ist Textviele eingebaute Typen, eigene Typen mit Einschränkungen
Anzahlnur ? * +beliebige Mindest-/Höchstwerte
Namensräumenicht unterstütztunterstützt
Aufwandkurz und einfachumfangreicher, aber genauer

Warum eine Schema-Validierung allein nicht reicht

DTD und XSD prüfen Struktur und (nur XSD) Datentypen einzelner Felder. Sie prüfen nicht, ob die Inhalte fachlich zueinander passen. Am Spielplan-Beispiel:

Fehler im DokumentDTDXSDWer findet ihn?
<datum>14.11.2026</datum> oder 2026-02-30neinja (kein xs:date)Schema
<preis>-5.00</preis>neinja, mit minInclusiveSchema
Vorstellung liegt außerhalb der Saison 2026/27neinneinGeschäftsregel
Ermäßigter Preis ist höher als der NormalpreisneinneinGeschäftsregel

Für solche logischen Fehler braucht man zusätzlich Geschäftsregeln: Plausibilitätsprüfungen im Programmcode, Regeln in Schematron (XML-basierte Regelsprache mit XPath-Ausdrücken, z. B. <sch:assert test="gesamt = sum(position/betrag)">), Unit-Tests mit Testdokumenten und – bei Standards wie der eRechnung – den offiziellen Validator, der Schema und Schematron prüft.

So wird es in der Prüfung gefragt

SD-02 · JSON Meistens

Vorkommen: JSON/XML zusammen 6/9 · JSON konkret: S23 T1 A4cb (JSON-Sensordaten in ein Relationenmodell übernehmen), W23 T1 A3c (14 P: Tabellen in JSON überführen, Embedding), S24 T1 A2c (JSON-Body eines Requests), W24 T1 A2c (8 P: Skript mit JSON-Ausgabe)

Syntax

JSON (JavaScript Object Notation) ist ein schlankes, textbasiertes Datenaustauschformat. Es ist das Standardformat von REST-APIs und dokumentenorientierten NoSQL-Datenbanken (z. B. MongoDB). Medientyp: application/json, Zeichenkodierung UTF-8. JSON kennt genau sechs Arten von Werten:

TypSchreibweiseBeispiel
Objekt{ "schlüssel": wert, … } – ungeordnete Menge von Schlüssel-Wert-Paaren{"kursNr": 101, "titel": "Rückenfit"}
Array[ wert, wert, … ] – geordnete Liste beliebiger Werte["MO", "MI", "FR"]
Stringin doppelten Anführungszeichen"Rückenfit", "2026-09-07"
Zahlohne Anführungszeichen, Dezimalpunkt, optional mit Exponent12, 45.00, -3.5, 1.2e3
Booleantrue oder false (klein geschrieben)"ausgebucht": false
nullnull – „kein Wert vorhanden“"start": null

Objekte und Arrays lassen sich beliebig verschachteln. Schlüssel sind immer Strings in doppelten Anführungszeichen. Ein Datum hat keinen eigenen Typ – es wird als String geschrieben, üblich im ISO-Format "JJJJ-MM-TT".

Beispiel: Die Tabelle Kurs eines Sportvereins …

kursNrtiteltrainerinplaetzeausgebuchtbeitragstart
101RückenfitMeyer12nein45.002026-09-07
102Yoga am AbendÖztürk15ja60.00(leer)

… als JSON-Dokument mit einem Array kurse:

{
  "kurse": [
    { "kursNr": 101, "titel": "Rückenfit", "trainerin": "Meyer", "plaetze": 12,
      "ausgebucht": false, "beitrag": 45.00, "start": "2026-09-07" },
    { "kursNr": 102, "titel": "Yoga am Abend", "trainerin": "Öztürk", "plaetze": 15,
      "ausgebucht": true, "beitrag": 60.00, "start": null }
  ]
}
Typische Syntaxfehler

So gehst du vor: Tabellen in JSON überführen

  1. Jede Zeile wird ein Objekt {…}, jede Spalte ein Schlüssel (Spaltennamen übernehmen, sofern nichts anderes verlangt ist).
  2. Mehrere Zeilen kommen in ein Array […], meist mit sprechendem Namen: {"kurse": [ … ]}.
  3. Datentyp je Spalte wählen: Zahlen ohne Anführungszeichen, Texte und Datumswerte mit, ja/nein → true/false, leere Zelle → null.
  4. Beziehungen (Fremdschlüssel) abbilden: entweder als Verweis (die ID wird übernommen) oder eingebettet (die zugehörigen Datensätze stehen als Array im übergeordneten Objekt) – siehe unten.
  5. Zum Schluss Klammern zählen und Kommas prüfen: Komma zwischen den Elementen, nie nach dem letzten.

Der umgekehrte Weg (S23 T1 A4cb: JSON-Sensordaten in ein Relationenmodell übernehmen): Jedes wiederkehrende Objekt wird eine Entität/Tabelle, ein eingebettetes Array wird eine eigene Tabelle mit Fremdschlüssel auf das übergeordnete Objekt.

Embedding und Referenz

In einer dokumentenorientierten Datenbank (Sammlungen von JSON-Dokumenten statt Tabellen) gibt es zwei Möglichkeiten, eine 1:n-Beziehung abzubilden. Beispiel: Abteilungen eines Sportvereins und ihre Trainingszeiten.

Referenz: zwei Sammlungen Sammlung „abteilungen“ {"abteilungId": 3, "name": "Handball", …} Sammlung „trainingszeiten“ {"zeitId": 31, "abteilungId": 3, "tag": "MO", …} {"zeitId": 32, "abteilungId": 3, "tag": "DO", …} Verweis über abteilungId Embedding: ein Dokument Sammlung „abteilungen“ {"abteilungId": 3, "name": "Handball", "leitung": "K. Brandt", "trainingszeiten": [ {"tag": "MO", "von": "18:00", …}, {"tag": "DO", "von": "19:30", …} ]} 2 Abfragen bzw. Verknüpfung nötig · keine Redundanz 1 Abfrage liefert alles · Daten gehören zur Abteilung gestrichelter Rahmen: eingebettete Unterdokumente (Array im Elternobjekt)
Abb. A-3: Referenz (wie ein Fremdschlüssel) und Embedding (Unterdokumente im Elternobjekt)

Referenz – Dokument in der Sammlung „abteilungen“

{ "abteilungId": 3, "name": "Handball", "leitung": "K. Brandt" }

Referenz – Dokumente in der Sammlung „trainingszeiten“ (verweisen über abteilungId)

[
  { "zeitId": 31, "abteilungId": 3, "tag": "MO", "von": "18:00", "halle": "Sporthalle Nord" },
  { "zeitId": 32, "abteilungId": 3, "tag": "DO", "von": "19:30", "halle": "Sporthalle Nord" }
]

Embedding – ein Dokument in der Sammlung „abteilungen“

{
  "abteilungId": 3,
  "name": "Handball",
  "leitung": "K. Brandt",
  "trainingszeiten": [
    { "tag": "MO", "von": "18:00", "halle": "Sporthalle Nord" },
    { "tag": "DO", "von": "19:30", "halle": "Sporthalle Nord" }
  ]
}
Einbetten (Embedding)Referenzieren
Aufbauzugehörige Datensätze als Array/Objekt im übergeordneten Dokumenteigene Dokumente; Verbindung über eine ID (wie ein Fremdschlüssel)
Leseneine Abfrage liefert alles – schnellmehrere Abfragen bzw. Verknüpfung (Lookup) nötig
gut geeignet, wenn …1:1 oder 1:wenige; die Daten werden fast immer zusammen gelesen und gehören nur zu diesem Elternobjekt (z. B. die Trainingszeiten einer Abteilung)sehr viele oder unbegrenzt wachsende Einträge; n:m-Beziehungen; Daten werden von vielen Dokumenten genutzt oder unabhängig geändert (z. B. Mitglieder, die in mehreren Abteilungen trainieren)
NachteilRedundanz und Änderungsaufwand, wenn dieselben Daten in vielen Dokumenten stecken; Dokumente können sehr groß werdenmehr Abfragen; die Konsistenz der Verweise muss die Anwendung sichern (keine Fremdschlüssel-Constraints)

JSON im Programm erzeugen

Manchmal soll ein Skript oder eine Funktion ihr Ergebnis als JSON ausgeben (W24 T1 A2c). In der Praxis erledigen das Bibliotheken (z. B. Jackson oder Gson in Java), in der Prüfung baut man den Text meist selbst zusammen. Dabei kommt es auf drei Dinge an: Klammern öffnen und schließen, Kommas nur zwischen den Elementen, Strings in Anführungszeichen (im Code als \" maskiert). Beispiel: Namen aus einem Array als JSON-Array ausgeben.

funktion namenAlsJson(namen : string[]) : string
  json : string := "["
  zähle i von 0 bis namen.length - 1
    wenn i > 0 dann
      json := json + ", "                  // Komma nur ZWISCHEN den Elementen
    Ende wenn
    json := json + "\"" + namen[i] + "\""   // Wert in Anführungszeichen
  Ende zähle
  json := json + "]"
  rückgabe json
Ende funktion

Ergebnis für ["Anna", "Ben", "Cem"]: ["Anna", "Ben", "Cem"]; für ein leeres Array: []. Zahlen und true/false werden ohne Anführungszeichen angehängt.

Achtung beim FilternWird nur ein Teil der Elemente ausgegeben, ist das erste ausgegebene Element nicht unbedingt das mit dem Index 0. Die Bedingung i > 0 setzt dann ein Komma zu viel. Man braucht eine andere Art, sich zu merken, ob schon etwas ausgegeben wurde.

JSON, XML, CSV und YAML im Vergleich

KriteriumJSONXML
AufbauObjekte, Arrays, Schlüssel-Wert-PaareElemente mit Start-/End-Tags, Attribute, Baum
DatentypenString, Zahl, Boolean, null eingebautohne Schema nur Text; Typen erst über XSD
Datenmengegering (keine End-Tags)größer (jeder Name steht doppelt)
Verarbeitungdirekt in Objekte von JavaScript/Java/C# abbildbar, schnell zu parsenDOM-/SAX-Parser, XPath, XSLT
PrüfungJSON Schema (weniger verbreitet)DTD, XSD, Schematron – sehr ausgereift
Kommentare, Namensräumeneinja
typischer EinsatzREST-APIs, Web und Apps, NoSQL-DatenbankeneRechnung, Behördenstandards, SOAP, Office-Formate, Dokumente

CSV (Comma-Separated Values): eine Textzeile je Datensatz, Werte durch Trennzeichen getrennt (in Deutschland oft ;), erste Zeile meist mit Spaltennamen. Keine Hierarchie, keine Datentypen, Probleme bei Trennzeichen im Text. Einsatz: Tabellen-Export und -Import.

kursNr;titel;plaetze
101;Rückenfit;12
102;Yoga am Abend;15

YAML: Struktur über Einrückung, Kommentare mit #, sehr gut lesbar. Einsatz vor allem für Konfigurationsdateien (Docker Compose, CI/CD-Pipelines). Fast jedes JSON-Dokument ist auch gültiges YAML.

kurs:
  kursNr: 101
  titel: Rückenfit
  tage: [MO, MI]   # Kommentar erlaubt
So wird es in der Prüfung gefragt

SD-03 · REST-Grundlagen & HTTP-Methoden Oft ↑

Vorkommen: REST/HTTP zusammen 4/9 (W21, S24, W24, S26), davon 3 in den letzten 4 Prüfungen · S24 T1 A2a/b (REST-Konzept 2 P, CRUD-Tabelle 6 P), S26 T1 A2ba/bc (REST-Konzept 3 P, zwei weitere HTTP-Methoden 6 P)

Begriffe

Die Prinzipien von REST

PrinzipBedeutungBeispiel (Bibliotheks-API)
Ressourcen mit eindeutiger URIAlles, worauf man zugreift (Medium, Leser, Ausleihe), ist eine Ressource mit eigener Adresse./medien/M-30815
/leser/4711/ausleihen
einheitliche SchnittstelleRessourcen werden nur über die Standardmethoden von HTTP bearbeitet; Ergebnisse werden mit Standard-Statuscodes gemeldet.GET liest, DELETE löscht – bei jeder Ressource gleich
RepräsentationenÜbertragen wird eine Darstellung der Ressource (meist JSON, auch XML), nicht die Ressource selbst. Der Client kann das Format wählen.Accept: application/json
ZustandslosigkeitJeder Request enthält alle nötigen Informationen (auch die Authentifizierung). Der Server speichert zwischen zwei Requests keinen Sitzungszustand des Clients.Token in jedem Request
Client-ServerOberfläche (Client) und Datenhaltung/Logik (Server) sind getrennt und unabhängig weiterentwickelbar.App, Website und Partner nutzen dieselbe API
CachefähigkeitAntworten geben an, ob und wie lange sie zwischengespeichert werden dürfen.Cache-Control: max-age=3600
SchichtensystemZwischen Client und Server dürfen Proxys, Load-Balancer oder Gateways liegen, ohne dass der Client es merkt.API-Gateway vor mehreren Servern

Selten gefragt: HATEOAS – Antworten enthalten Links auf mögliche Folgeaktionen, z. B. zur Verlängerung einer Ausleihe.

Request: Methode + URI (+ JSON-Body), z. B. GET /medien/M-30815 Smartphone-App Web-Frontend Partner-System HTTPS REST-API (Server) /medien /medien/{medienNr} /leser/{leserNr} /leser/{nr}/ausleihen /leser/{nr}/vormerkungen … Daten- bank Response: Statuscode + Repräsentation (meist JSON) Zustandslos: Jeder Request enthält alle nötigen Informationen (z. B. Token); der Server speichert keine Sitzung.
Abb. A-4: Verschiedene Clients greifen über HTTPS auf die Ressourcen einer REST-API zu
Merke: Was in die Antwort auf „Erläutern Sie das Konzept einer REST-API“ gehört Mindestens drei Aspekte in ganzen Sätzen: Ressourcen mit eindeutiger URI/URL · Zugriff über die HTTP-Methoden (einheitliche Schnittstelle) · Austausch von Repräsentationen (meist JSON) · zustandslos (jede Anfrage ist in sich vollständig) · Client und Server lose gekoppelt. Nur „REST ist eine Schnittstelle im Internet“ reicht nicht.

CRUD und HTTP-Methoden

CRUD steht für die vier Grundoperationen auf Daten: Create, Read, Update, Delete. Bei REST übernimmt die HTTP-Methode die Rolle des Verbs, die URI benennt nur die Ressource.

CRUDHTTP-MethodeBeispiel (Bibliothek)typische Antwort
Create – anlegenPOST (Server vergibt die ID)
PUT, wenn der Client die URI/ID festlegt
POST /leser/4711/vormerkungen201 Created + Header Location
Read – lesenGETGET /medien?titel=Momo200 OK + Daten
Update – ändernPUT (vollständig ersetzen)
PATCH (einzelne Felder ändern)
PATCH /leser/4711200 OK oder 204 No Content
Delete – löschenDELETEDELETE /leser/4711/vormerkungen/912204 No Content (oder 200)

Weitere Methoden: HEAD (wie GET, aber nur die Header – z. B. um Größe oder Änderungsdatum zu prüfen) und OPTIONS (welche Methoden sind für eine Ressource erlaubt?).

Sicher und idempotent

Warum das wichtig ist: Bei schlechter Verbindung weiß ein Client oft nicht, ob seine Anfrage angekommen ist. Idempotente Anfragen darf er (oder ein Proxy) gefahrlos wiederholen – bei nicht idempotenten Anfragen kann eine Wiederholung Schaden anrichten.

PUT oder PATCH?

Die Ressource /leser/4711 sieht so aus: {"leserNr": 4711, "name": "Tom Berger", "email": "tom@mail.example", "newsletter": false}. Nur die E-Mail-Adresse soll sich ändern:

PUT /v2/leser/4711
Content-Type: application/json

{"leserNr": 4711, "name": "Tom Berger",
 "email": "t.berger@mail.example",
 "newsletter": false}
PATCH /v2/leser/4711
Content-Type: application/json

{"email": "t.berger@mail.example"}

PUT überträgt die vollständige neue Repräsentation und ersetzt die alte. Schickt man bei PUT nur ein Feld, wären die übrigen danach leer bzw. auf Standardwerte gesetzt. PATCH überträgt nur die Änderung.

Endpunkte entwerfen

Anforderung (Bibliothek)schlechtbesser
alle DVDs anzeigenGET /getAllDvdsGET /medien?typ=dvd
Leser 4711 löschenGET /leser/delete?id=4711DELETE /leser/4711
Vormerkung anlegenPOST /neueVormerkungPOST /leser/4711/vormerkungen
E-Mail-Adresse eines Lesers ändernPOST /leser/4711/updatePATCH /leser/4711
Typische Fehler

Ablauf eines API-Aufrufs

In S24 T1 A2e (11 P) sollte der Ablauf App → WebService → Datenbank als Sequenzdiagramm mit alt-Fragment gezeichnet werden (Notation siehe Block 03 UML). So sieht das für eine einfache Leseanfrage aus:

:App :REST-API :Datenbank GET /v2/medien/M-30815 Medium M-30815 lesen (SELECT) Datensatz bzw. leere Ergebnismenge alt [Medium gefunden] 200 OK + JSON des Mediums [else] 404 Not Found
Abb. A-5: Sequenzdiagramm eines GET-Aufrufs mit alt-Fragment (synchrone Nachricht = gefüllte Spitze, Antwort = gestrichelt)

REST und SOAP

RESTSOAP
ArtArchitekturstilProtokoll (W3C-Standard)
Datenformatbeliebig, meist JSONnur XML (SOAP-Envelope mit Header und Body)
Beschreibungoptional, z. B. OpenAPIverbindlich per WSDL
AufrufHTTP-Methoden auf Ressourcen-URIsmeist ein Endpunkt, Operation steht im XML (fast immer POST)
Eigenschaftenleichtgewichtig, cachebar, zustandslosumfangreich, mit Zusatzstandards (WS-Security, Transaktionen)
EinsatzWeb, Apps, öffentliche APIsBanken, Behörden, ältere Unternehmenssysteme
So wird es in der Prüfung gefragt

SD-04 · HTTP-Request/Response & Statuscodes Oft ↑

Vorkommen: REST/HTTP zusammen 4/9 · W21 T1 A3c (Ursache für HTTP 404, 2 P), S24 T1 A2c/d (Bestandteile eines Requests 3 P, Statuscode-Klassen 3 P), W24 T2 A2a (HTTP-Antwort im Code bauen, 10 P), S26 T1 A2bb (Parameter einer URL beschreiben, 3 P)

HTTP in Kürze

HTTP (Hypertext Transfer Protocol) ist ein Protokoll der Anwendungsschicht nach dem Request-Response-Prinzip: Der Client sendet eine Anfrage, der Server beantwortet sie. HTTP ist zustandslos – jede Anfrage steht für sich (Sitzungen entstehen erst durch Cookies oder Tokens). Standardport 80; HTTPS ist HTTP über eine TLS-verschlüsselte Verbindung (Port 443) und heute der Normalfall. Bei HTTP/1.1 sind die Nachrichten reiner Text; HTTP/2 und HTTP/3 übertragen binär, Methoden, Header und Statuscodes bleiben aber gleich.

Aufbau von Request und Response

Request (Client → Server) POST /v2/leser/4711/vormerkungen HTTP/1.1 Host: api.stadtbibliothek.example Content-Type: application/json Accept: application/json Authorization: Bearer eyJhbGciOiJIUzI1NiJ9… Content-Length: 23 {"medienNr": "M-30815"} (Leerzeile) ① Request-Zeile: Methode, Pfad, Version ② Header (Metadaten): Zielserver, Formate, Zugangsdaten, Länge ③ Leerzeile: Ende der Header ④ Body: Nutzdaten (hier JSON) Response (Server → Client) HTTP/1.1 201 Created Content-Type: application/json; charset=utf-8 Location: /v2/leser/4711/vormerkungen/912 Content-Length: 59 {"vormerkungId": 912, "medienNr": "M-30815", "position": 3} (Leerzeile) ① Statuszeile: Version, Statuscode, Text ② Header: Format, URI der neuen Ressource, Länge des Bodys ③ Leerzeile ④ Body: Repräsentation (JSON)
Abb. A-6: Ein HTTP-Request (Vormerkung anlegen) und die zugehörige Response
HeaderinBedeutung
HostRequestName des Zielservers (Pflicht bei HTTP/1.1)
Content-TypebeideFormat des Bodys: application/json, application/xml, text/plain, text/html, ggf. mit charset=utf-8
AcceptRequestFormat, das der Client als Antwort haben möchte
AuthorizationRequestZugangsdaten, z. B. Bearer <Token> oder Basic <Base64(name:passwort)>
X-API-KeyRequestAPI-Schlüssel (eigener Header, der Name ist je nach API verschieden)
Content-LengthbeideLänge des Bodys in Bytes
LocationResponseURI der neu angelegten Ressource (bei 201) oder Ziel einer Weiterleitung (bei 3xx)
Cache-ControlResponseob und wie lange die Antwort zwischengespeichert werden darf
Set-Cookie / CookieResp. / Req.Cookie setzen bzw. mitsenden (z. B. Sitzungs-ID)
User-AgentRequestName und Version der Client-Software

Aufbau einer URL

https :// api.stadtbibliothek.example :443 /v2/medien ?titel=Momo&seite=2 #treffer Schema Host (Domain) Port Pfad Query-String Fragment Protokoll Server optional Parameter titel und seite Version + Ressource Sprungmarke, nicht an Server
Abb. A-7: Bestandteile einer URL (Port 443 ist bei https Standard und wird meist weggelassen)

API-Schlüssel

Ein API-Schlüssel (API key) ist eine eindeutige, geheime Zeichenfolge, mit der sich eine Anwendung (nicht eine Person) gegenüber einer API ausweist. Zweck: nur registrierte Clients erhalten Zugriff, Anfragen lassen sich einem Kunden zuordnen (Abrechnung, Statistik), und die Anzahl der Anfragen lässt sich begrenzen (Rate-Limiting, Überschreitung → 429 Too Many Requests). Übertragung immer über HTTPS, besser im Header als in der URL, und nie im öffentlich einsehbaren Quellcode ablegen. Ein API-Schlüssel ersetzt keine Benutzeranmeldung – dafür gibt es Tokens (z. B. OAuth 2.0).

Statuscodes

KlasseBedeutung
1xxInformation – Anfrage erhalten, Verarbeitung läuft
2xxErfolg – Anfrage erfolgreich verarbeitet
3xxUmleitung – der Client muss eine andere URL aufrufen bzw. seinen Cache verwenden
4xxClient-Fehler – die Anfrage ist fehlerhaft oder nicht erlaubt; unverändert wiederholt scheitert sie erneut
5xxServer-Fehler – die Anfrage war in Ordnung, der Server konnte sie aber nicht ausführen
CodeName
200OK
201Created
204No Content
301 / 302Moved Permanently / Found
304Not Modified
400 / 401Bad Request / Unauthorized
403 / 404Forbidden / Not Found
405 / 409Method Not Allowed / Conflict
415 / 429Unsupported Media Type / Too Many Requests
500 / 503Internal Server Error / Service Unavailable
Codewann (am Beispiel der Bibliotheks-API)
200GET liefert das Medium; PUT/PATCH erfolgreich und die geänderte Ressource steht im Body
201POST hat eine Vormerkung angelegt; der Header Location nennt ihre URI
204erfolgreich, aber bewusst ohne Body, z. B. nach dem Löschen einer Vormerkung
301Die Ressource liegt dauerhaft unter einer neuen URL (steht in Location); Clients sollen künftig die neue URL nutzen. 302/307: nur vorübergehend
400Anfrage formal oder inhaltlich ungültig: kaputtes JSON, Pflichtfeld fehlt, Datum im falschen Format
401nicht authentifiziert: Token bzw. API-Schlüssel fehlt, ist abgelaufen oder falsch – „Wer bist du?“
403authentifiziert, aber nicht berechtigt: Leser 4711 will die Ausleihen von Leser 4712 sehen – „Ich weiß, wer du bist, aber das darfst du nicht.“
404unter dieser URL gibt es keine Ressource: unbekannte Mediennummer, falscher Pfad
405Methode für diese Ressource nicht erlaubt, z. B. DELETE /medien
409Widerspruch zum aktuellen Zustand: Medium ist bereits vom selben Leser vorgemerkt
500unerwarteter Fehler im Server (z. B. nicht abgefangene Exception)
503Dienst vorübergehend nicht verfügbar (Wartung, Überlastung, Datenbank nicht erreichbar); oft mit Header Retry-After
Typische Fallen

Content-Length zählt Bytes, nicht Zeichen

In UTF-8 belegen ASCII-Zeichen (A–Z, a–z, Ziffern, Leerzeichen, { } " : usw.) je 1 Byte, ä ö ü Ä Ö Ü ß je 2 Bytes, das Eurozeichen € 3 Bytes, Emojis 4 Bytes. Gezählt wird nur der Body, nicht die Header.

BodyZeichenBytes = Content-Length
Bücherei geöffnet1719 (ü und ö je +1)
Gebühr: 2,50 €1417 (ü +1, € +2)

Eine HTTP-Antwort im Code zusammenbauen

In W24 T2 A2a war eine Klasse HttpResponse vorgegeben und eine Methode zu schreiben, die eine vollständige Antwort mit Statuscode, Content-Type, Content-Length (in Bytes) und Body erzeugt. Das Muster an einem einfachen Beispiel – ein „Lebenszeichen“-Endpunkt der Bibliotheks-API, der immer mit einem kurzen Text antwortet (Methoden wie in der Klasse HttpResponse des Belegsatzes):

funktion createPingResponse() : HttpResponse
  body : string := "Bücherei-API läuft"
  antwort : HttpResponse := new HttpResponse()
  antwort.setStatus(200)
  antwort.setHeader("Content-Type", "text/plain; charset=utf-8")
  antwort.setHeader("Content-Length", body.byteLength().toString())   // 20, nicht 18!
  antwort.setBody(body)
  rückgabe antwort
Ende funktion
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 20

Bücherei-API läuft

Prüfreihenfolge in einem Endpunkt. Ein Endpunkt prüft der Reihe nach und kehrt beim ersten Problem sofort mit dem passenden Code zurück („frühes Return“):

  1. Ist der Client authentifiziert (Token/API-Schlüssel vorhanden und gültig)? sonst 401
  2. Darf er diese Ressource bzw. Aktion nutzen? sonst 403
  3. Sind die Eingaben gültig (Pflichtfelder, Formate)? sonst 400
  4. Gibt es die Ressource? sonst 404 · Widerspricht die Aktion dem aktuellen Zustand? 409
  5. Aktion ausführen → 200, 201 oder 204; ist ein benötigter Dienst nicht erreichbar → 503; unerwarteter Fehler → 500
So wird es in der Prüfung gefragt

SD-05 · eRechnung Sonstige ⚠

Vorkommen: 1/9, aber in der vorletzten Prüfung: W25 T1 A2b (9 P: englischer Text – Hauptziel, Aspekte einer digitalen Rechnung) und A3 (Transportverschlüsselung 4 P, Konformität sicherstellen 3 P, Online-Prüfseite 6 P, XSD-Validierung reicht nicht 6 P). Wegen der neuen gesetzlichen Pflicht ein naheliegendes Thema für weitere Prüfungen.

Was ist eine eRechnung?

Nach der EU-Richtlinie 2014/55/EU und § 14 UStG ist eine elektronische Rechnung (eRechnung, e-invoice) eine Rechnung, die in einem strukturierten elektronischen Format ausgestellt, übermittelt und empfangen wird und eine automatische und elektronische Verarbeitung ermöglicht. In Deutschland muss das Format der europäischen Norm EN 16931 entsprechen (oder mit ihr kompatibel sein).

Merke Das Hauptziel der eRechnung ist die automatische Verarbeitung: Die Rechnungsdaten werden ohne Abtippen direkt in die Software des Empfängers (Buchhaltung, ERP) übernommen und geprüft. Eine für Menschen lesbare Darstellung ist zweitrangig.
Eine PDF-Rechnung ist deshalb keine eRechnung (sondern eine „sonstige Rechnung“) – ebenso wenig ein Scan oder ein Foto einer Papierrechnung.

Zwei Aspekte einer digitalen Rechnung: Der visuelle Aspekt erlaubt einem Menschen, den Inhalt zu sehen und zu lesen (z. B. als PDF). Der Datenaspekt erlaubt einem Computer, die enthaltenen Informationen strukturiert zu verarbeiten (z. B. als XML mit festgelegten Feldern für Rechnungsnummer, Beträge, Steuersätze). Eine PDF hat nur den visuellen Aspekt, eine XRechnung nur den Datenaspekt, ZUGFeRD beide.

Vorteile: keine manuelle Erfassung, dadurch weniger Fehler und schnellere Bearbeitung und Zahlung; geringere Kosten für Druck, Porto und Erfassung; einfache, durchsuchbare Archivierung; automatische Prüfung (Pflichtangaben, Rechenwerte); Grundlage für digitale Meldeverfahren der Steuerverwaltung. Herausforderungen: Software muss eRechnungen erzeugen, prüfen, anzeigen und revisionssicher im Originalformat archivieren; Abläufe und Stammdaten müssen angepasst werden.

Pflicht in Deutschland (Stand 2026)

ZeitpunktRegelung
seit 27.11.2020B2G (an öffentliche Auftraggeber): Lieferanten des Bundes müssen eRechnungen senden; die Länder haben eigene, ähnliche Regelungen.
seit 01.01.2025B2B: Alle inländischen Unternehmen müssen eRechnungen empfangen können.
bis 31.12.2026Übergang beim Versand: Papierrechnungen und sonstige elektronische Formate sind noch erlaubt; eine PDF nur mit Zustimmung des Empfängers.
bis 31.12.2027Übergang nur noch für Unternehmen mit einem Gesamtumsatz im Vorjahr von höchstens 800.000 € (außerdem für vereinbarte EDI-Verfahren).
ab 01.01.2028Alle Unternehmen müssen im B2B-Bereich eRechnungen ausstellen.

Ausnahmen: Kleinbetragsrechnungen bis 250 € (brutto) und Fahrausweise. Rechnungen an Privatkunden (B2C) sind nicht betroffen. eRechnungen müssen im Originalformat (also als XML) aufbewahrt werden (GoBD) – ein ausgedrucktes Bild reicht nicht.

Formate

Die EN 16931 legt ein semantisches Datenmodell der „Kernrechnung“ fest (welche Angaben es gibt und was sie bedeuten, z. B. BT-1 Rechnungsnummer) und lässt zwei XML-Syntaxen zu: UBL (Universal Business Language) und UN/CEFACT CII (Cross Industry Invoice). In Deutschland sind zwei Formate verbreitet:

XRechnungZUGFeRDPDF / Scan
Artreines XML (UBL oder CII); deutsche Ausprägung (CIUS) der EN 16931, gepflegt von der KoSIThybrid: PDF/A-3-Dokument mit eingebetteter XML-Datei (CII); baugleich mit dem französischen Factur-XBild bzw. Text ohne Datenstruktur
für Menschennur mit Viewer/Visualisierung lesbarPDF direkt lesbarlesbar
für Softwaredirekt verarbeitbarXML-Teil direkt verarbeitbarnur per Abtippen/Texterkennung
Einsatzöffentliche Auftraggeber (B2G), zunehmend B2B; öffentliche Empfänger verlangen meist die Leitweg-IDB2B, vor allem wenn der Empfänger die Rechnung auch ohne Spezialsoftware lesen sollB2B nur in der Übergangszeit
eRechnung?jaja, ab Profil EN 16931 (nicht die Profile MINIMUM und BASIC WL)nein

Bei ZUGFeRD ist der XML-Teil maßgeblich: Weichen PDF und XML voneinander ab, gelten die XML-Daten. Die Leitweg-ID ist eine Kennung des öffentlichen Rechnungsempfängers (z. B. einer bestimmten Behörde oder Einrichtung). Sie wird vom Auftraggeber mitgeteilt, steht in der XRechnung im Feld „Käuferreferenz“ (BT-10) und sorgt dafür, dass die Rechnung automatisch an die zuständige Stelle weitergeleitet wird.

PDF / Scan RECHNUNG nur visueller Aspekt Daten nur durch Abtippen oder Texterkennung keine eRechnung XRechnung <Invoice> <cbc:ID>… <cbc:IssueDate>… <cac:InvoiceLine> … </Invoice> nur Datenaspekt (XML in UBL oder CII) Anzeige über einen Viewer eRechnung ZUGFeRD RECHNUNG XML PDF/A-3 eingebettet visuell (PDF) + Daten (XML) XML-Teil ist maßgeblich Profil mind. EN 16931 eRechnung
Abb. A-8: PDF, XRechnung und ZUGFeRD – nur strukturierte Daten machen eine eRechnung

So sieht der Anfang einer echten XRechnung im UBL-Format aus (Auszug, Beispiel einer Tischlerei an eine Behörde; cbc und cac sind Namensraum-Präfixe):

<ubl:Invoice xmlns:ubl="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
    xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">
  <cbc:CustomizationID>urn:cen.eu:en16931:2017#compliant#…:xrechnung_3.0</cbc:CustomizationID>
  <cbc:ID>TB-2026-0815</cbc:ID>                              <!-- Rechnungsnummer (BT-1) -->
  <cbc:IssueDate>2026-10-02</cbc:IssueDate>                 <!-- Rechnungsdatum -->
  <cbc:DueDate>2026-11-01</cbc:DueDate>                     <!-- Fälligkeit -->
  <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>            <!-- 380 = Handelsrechnung -->
  <cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
  <cbc:BuyerReference>04011000-1234512345-06</cbc:BuyerReference>  <!-- Leitweg-ID -->
  <!-- … Verkäufer, Käufer, Zahlungsangaben, Steuern … -->
  <cac:LegalMonetaryTotal>                <!-- Summen: Positionen, netto, brutto, Zahlbetrag -->
    <cbc:LineExtensionAmount currencyID="EUR">1200.00</cbc:LineExtensionAmount>
    <cbc:TaxExclusiveAmount currencyID="EUR">1200.00</cbc:TaxExclusiveAmount>
    <cbc:TaxInclusiveAmount currencyID="EUR">1428.00</cbc:TaxInclusiveAmount>
    <cbc:PayableAmount currencyID="EUR">1428.00</cbc:PayableAmount>
  </cac:LegalMonetaryTotal>
  <!-- … Rechnungspositionen (cac:InvoiceLine) … -->
</ubl:Invoice>

Übertragungswege

Das Gesetz schreibt keinen bestimmten Weg vor. Üblich sind:

Rechnungssteller (Software, ERP) eRechnung erzeugen (XML) prüfen XSD + Schematron (Validator) übermitteln Empfänger prüft und bucht automatisch E-Mail (Anhang) Portal (z. B. ZRE, OZG-RE) Peppol-Netzwerk EDI / Web-API vor jedem Versand archiviert im Originalformat
Abb. A-9: Weg einer eRechnung vom Rechnungssteller zum Empfänger

Validierung: Entspricht die Rechnung der Spezifikation?

Eine eRechnung wird in zwei Stufen geprüft:

  1. Schema-Validierung (XSD von UBL bzw. CII): Struktur, Pflichtelemente, Reihenfolge, Datentypen (Datum, Dezimalzahl, Codes). Sie stellt die formale Korrektheit sicher.
  2. Schematron-Prüfung: Geschäftsregeln der EN 16931 und der XRechnung, die sich mit einem Schema nicht ausdrücken lassen – z. B. „Summe der Positionsnettobeträge = Nettogesamtbetrag“, „Bruttobetrag = Nettobetrag + Umsatzsteuer“, „bei XRechnung ist die Käuferreferenz (Leitweg-ID) anzugeben“.

Beides erledigt der KoSIT-Validator, das offizielle Prüfwerkzeug: frei verfügbar (Open Source), lokal ausführbar und auch in automatisierte Tests einbindbar; er erstellt einen Prüfbericht. Bei der Entwicklung einer Rechnungssoftware sichern außerdem ab: die verbindlichen Anforderungen der Spezifikation konsequent umsetzen, erprobte Bibliotheken nutzen, automatisierte Tests mit den offiziellen Testrechnungen, Testläufe mit Empfängern bzw. deren Portalen (Interoperabilität) und die Validierung als festen Schritt vor jedem Versand.

Datenschutz und Sicherheit

Englischer Fachtext: so gehst du vor

In W25 kam die eRechnung als englischer Text. Gefragt wird nicht nach einer Übersetzung, sondern nach dem Inhalt in eigenen Worten auf Deutsch. Erst die Frage lesen, dann im Text die passende Stelle suchen (Schlüsselwörter wie main objective, aspects, from … until), dann in ganzen Sätzen antworten. Hilfreiche Vokabeln:

EnglischDeutschEnglischDeutsch
invoice / to issueRechnung / ausstellenrecipient / consentEmpfänger / Zustimmung
structured formatstrukturiertes Formatturnover / thresholdUmsatz / Grenzwert
transmission channelÜbertragungswegtransition periodÜbergangsfrist
to comply witheinhalten, entsprechento be exemptausgenommen sein
embeddedeingebettetto prevailVorrang haben, maßgeblich sein
public authorityBehörderouting IDLeitweg-ID
So wird es in der Prüfung gefragt

B · Belegsatz

Für diesen Block legt die IHK keine Notationshilfen bei. Der Belegsatz enthält deshalb nur die Anlagen zur Ausgangssituation (Szenario, API-Dokumentation, Beispielnachrichten, Klassen, XML- und JSON-Daten, englischer Text). Keine Erklärungen.

Anlage 1 · Ausgangssituation

Die Aufgaben dieses Blocks beziehen sich auf die folgende Ausgangssituation:

Die FrischeKiste Nordheide GmbH mit Sitz in Heidmoor beliefert Haushalte, Firmen und Einrichtungen mit Obst- und Gemüsekisten aus der Region. Rund 2.400 Privatkunden haben ein Abonnement, dazu kommen etwa 60 Geschäftskunden, darunter Büros, Kantinen sowie die Kitas und Schulen der Stadt Heidmoor. Die Ware stammt von 28 Erzeugerbetrieben. Ausgeliefert wird dienstags bis freitags mit sechs Transportern. Der Umsatz betrug 2025 rund 4,3 Mio. €, für 2026 werden rund 4,6 Mio. € erwartet.

Die bisherige Lösung aus Webshop, Tabellenkalkulation und E-Mail soll durch die Plattform „KistenPortal“ ersetzt werden:

Sie sind Auszubildende/r zum Fachinformatiker/zur Fachinformatikerin Anwendungsentwicklung bei der Kranich Softwarehaus GmbH in Lüneburg, die das KistenPortal entwickelt.

Anlage 2 · API-Dokumentation „KistenPortal-API“ (Auszug)

Basis-URL: https://api.frischekiste.example/v1

Ressourcen
RessourceSchlüsselBeschreibung
kistenkisteIdKistenarten (Obst-, Gemüse-, Mischkisten), siehe Anlage 7
kundenkundenNrKundenkonten, siehe Anlage 8
abosaboIdAbonnements eines Kunden (Unterressource von kunden)
lieferadressenadrIdLieferadressen eines Kunden (Unterressource von kunden)
bestellungenbestellNrBestellungen und Lieferungen; Attribut datum
reklamationenreklaIdReklamationen zu einer Bestellung (Unterressource von bestellungen)
tourentourNrLiefertouren eines Tages
Endpunkte (Auszug)
MethodeEndpunktBeschreibungbei Erfolg
GET/kistenalle Kistenarten200 OK
GET/kisten/{kisteId}eine Kistenart200 OK
GET/kunden/{kundenNr}/abosalle Abos eines Kunden200 OK
GET/kunden/{kundenNr}/abos/{aboId}ein Abo200 OK
POST/kunden/{kundenNr}/abosneues Abo anlegen201 Created, Header Location
GET/touren/{datum}/{tourNr}/stoppsStopps einer Tour (Fahrer-App)200 OK

Repräsentation eines Abos (Antwort auf GET /v1/kunden/10427/abos/5531):

{
  "aboId": 5531,
  "kundenNr": 10427,
  "kisteId": "K-OBST-M",
  "rhythmus": "woechentlich",
  "liefertag": "DI",
  "lieferadresseId": 1,
  "status": "aktiv",
  "pausiertBis": null
}

Erlaubte Werte: rhythmus: woechentlich | 14-taegig · liefertag: DI | MI | DO | FR · status: aktiv | pausiert | gekuendigt · pausiertBis: Datum oder null

Anlage 3 · Beispiel: Abo über die Kunden-App anlegen

Request

POST /v1/kunden/10427/abos HTTP/1.1
Host: api.frischekiste.example
Content-Type: application/json
Accept: application/json
X-API-Key: app-7Fq2-Lx91
Content-Length: 88

{"kisteId": "K-GEM-L", "rhythmus": "14-taegig", "liefertag": "FR", "lieferadresseId": 2}

Response

HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
Location: /v1/kunden/10427/abos/5547
Content-Length: 162

{"aboId": 5547, "kundenNr": 10427, "kisteId": "K-GEM-L", "rhythmus": "14-taegig", "liefertag": "FR", "lieferadresseId": 2, "status": "aktiv", "pausiertBis": null}

Anlage 4 · Klassen und Methoden für die Programmieraufgaben (Auszug)

KistenController - katalog : KistenKatalog - schluessel : ApiSchluessel + handleGetKiste(request : HttpRequest) : HttpResponse - createErrorResponse(statusCode : integer, meldung : string) : HttpResponse HttpRequest + getMethode() : string + getPfadParameter(name : string) : string + getHeader(name : string) : string + getQueryParameter(name : string) : string HttpResponse + HttpResponse() + setStatus(code : integer) : void + setHeader(name : string, wert : string) : void + setBody(inhalt : string) : void KistenKatalog + istVerfuegbar() : boolean + findeKiste(kisteId : string) : Kiste ApiSchluessel + istGueltig(schluessel : string) : boolean Kiste - kisteId : string - bezeichnung : string - groesse : string - preis : double - bio : boolean + toJson() : string Stopp - position : integer - kundenNr : integer - ort : string - anzahlKisten : integer - zugestellt : boolean + isZugestellt() : boolean List<T> + add(t : T) : void + get(i : integer) : T + size() : integer

Hinweise:

  • Für alle Attribute existieren Get-Methoden (z. B. getOrt(), getAnzahlKisten(); bei boolean: isBio(), isZugestellt()).
  • getPfadParameter, getHeader und getQueryParameter liefern null, wenn der Parameter bzw. Header nicht vorhanden ist. findeKiste liefert null, wenn es keine Kiste mit dieser ID gibt.
  • Kiste.toJson() liefert die JSON-Repräsentation der Kiste, z. B. {"kisteId": "K-GEM-L", "bezeichnung": "Gemüsekiste groß", …}.
  • Zeichenketten (string): text.length() liefert die Anzahl der Zeichen, text.byteLength() die Anzahl der Bytes in UTF-8-Kodierung. Zeichenketten werden mit + verkettet; Zahlen werden dabei automatisch in Text umgewandelt. zahl.toString() wandelt eine Zahl in eine Zeichenkette um. Ein Anführungszeichen innerhalb einer Zeichenkette wird als \" geschrieben.

Anlage 5 · Wochenangebot des Erzeugerbetriebs „Hof Brammer“ (KW 46) mit DTD

XML-Dokument wochenangebot_kw46.xml

 1  <?xml version="1.0" encoding="UTF-8"?>
 2  <!DOCTYPE wochenangebot SYSTEM "wochenangebot.dtd">
 3  <wochenangebot kw="46">
 4    <erzeuger erzeugerId="E07">
 5      <name>Hof Brammer</name>
 6      <ort>Wiesede</ort>
 7      <biozertifikat>DE-ÖKO-006</biozertifikat>
 8    </erzeuger>
 9    <artikel artNr="A-101" einheit="kg">
10      <bezeichnung>Möhren, lose</bezeichnung>
11      <menge>120</menge>
12      <preis>1.40</preis>
13    </artikel>
14    <artikel artNr="A-102" einheit="stueck">
15      <bezeichnung>Kürbis Hokkaido</Bezeichnung>
16      <menge>40</menge>
17      <preis>2.10</preis>
18      <hinweis>nur bis KW 48 lieferbar</hinweis>
19    </artikel>
20    <artikel artNr="A-103" einheit="bund">
21      <bezeichnung>Lauchzwiebeln</bezeichnung>
22      <preis>0.90</preis>
23      <menge>60</menge>
24    </artikel>
25    <artikel artNr="A-101" einheit="Kilo">
26      <bezeichnung>Rote Bete</bezeichnung>
27      <menge>35<menge>
28      <preis>1.80</preis>
29      <lieferant>Hof Brammer</lieferant>
30    </artikel>
31    <artikel artNr=A-105>
32      <bezeichnung>Feldsalat</bezeichnung>
33      <menge>15</menge>
34      <preis>7.50</preis>
35    </artikel>
36  </wochenangebot>

Externe DTD wochenangebot.dtd

 1  <!ELEMENT wochenangebot (erzeuger, artikel+)>
 2  <!ATTLIST wochenangebot kw   CDATA #REQUIRED
 3                          jahr CDATA #REQUIRED>
 4  <!ELEMENT erzeuger (name, ort, biozertifikat?)>
 5  <!ATTLIST erzeuger erzeugerId ID #REQUIRED>
 6  <!ELEMENT name (#PCDATA)>
 7  <!ELEMENT ort (#PCDATA)>
 8  <!ELEMENT biozertifikat (#PCDATA)>
 9  <!ELEMENT artikel (bezeichnung, menge, preis, hinweis*)>
10  <!ATTLIST artikel artNr   ID              #REQUIRED
11                    einheit (kg|stueck|bund) "kg">
12  <!ELEMENT bezeichnung (#PCDATA)>
13  <!ELEMENT menge (#PCDATA)>
14  <!ELEMENT preis (#PCDATA)>
15  <!ELEMENT hinweis (#PCDATA)>

Anlage 6 · Lieferschein (XML)

 1  <?xml version="1.0" encoding="UTF-8"?>
 2  <!DOCTYPE lieferschein SYSTEM "lieferschein.dtd">
 3  <lieferschein nr="LS-2026-1187" datum="2026-11-10">
 4    <kunde kundenNr="20015">
 5      <name>Kita Sonnenblume</name>
 6      <adresse>Am Mühlenbach 3, 21391 Heidmoor</adresse>
 7    </kunde>
 8    <position>
 9      <kiste>K-OBST-M</kiste>
10      <anzahl>4</anzahl>
11    </position>
12    <position>
13      <kiste>K-GEM-L</kiste>
14      <anzahl>2</anzahl>
15      <bemerkung>ohne Sellerie</bemerkung>
16      <bemerkung>Kühlware zuerst ausladen</bemerkung>
17    </position>
18    <fahrer>T. Ohlsen</fahrer>
19  </lieferschein>

Anlage 7 · Tabellen der Kistenarten (bisherige Datenhaltung)

Kiste
kisteIdbezeichnunggroessepreisbiogewichtKgsaisonEnde
K-OBST-MObstkiste mittelM18.50ja4.5
K-GEM-LGemüsekiste großL27.90ja8.02027-03-31
K-MIX-SMischkiste kleinS14.20nein3.0
Kisteninhalt (Auszug)
kisteIdartikelmengeeinheit
K-OBST-MÄpfel Elstar1.5kg
K-OBST-MBirnen Conference1kg
K-OBST-MBananen6Stück
K-GEM-LMöhren2kg
K-GEM-LKürbis Hokkaido1Stück
…………

Eine leere Zelle bedeutet: kein Wert vorhanden.

Anlage 8 · Tabellen der Kunden und Lieferadressen (Auszug)

Kunde
kundenNrnamekundentypemailnewsletter
10427Jana Petersenprivatj.petersen@mail.exampleja
20015Kita Sonnenblumeoeffentlichverwaltung@kita-sonnenblume.examplenein
Lieferadresse
adrIdkundenNrstrasseplzortablageort
110427Lindenweg 421391HeidmoorGarage
210427Hafenstraße 1821423Kleinmoor
320015Am Mühlenbach 321391HeidmoorKüche, Hintereingang

Eine leere Zelle bedeutet: kein Wert vorhanden.

Anlage 9 · Stopps der Tour T3 am 10.11.2026 (Testdaten)

positionkundenNrortanzahlKistenzugestellt
110427Heidmoor2true
220015Heidmoor6false
310533Wiesede1false
410871Kleinmoor3true
520022Wiesede4false

Die Stopps liegen in einer Liste List<Stopp> in der Reihenfolge der Tabelle vor (Klasse Stopp siehe Anlage 4).

Anlage 10 · JSON-Syntaxbeschreibung

// JSON-Syntaxbeschreibung
// wert kann sein: "zeichenkette", zahl, true, false, null, objekt, array
{
    "attributname": wert,
    ...,
    "objektname": {
        "attributname": wert,
        ...
    },
    "arrayname": [
        wert,
        ...
    ]
}

Anlage 11 · Fachtext zur eRechnung

E-invoicing in Germany: what businesses need to know

Since 1 January 2025, every business in Germany has to be able to receive electronic invoices from other businesses (B2B). Under the new rules, an e-invoice is an invoice that is issued, transmitted and received in a structured electronic format which complies with the European standard EN 16931 and allows the data to be processed automatically. A PDF file attached to an e-mail is therefore no longer regarded as an e-invoice but as an “other invoice”. Invoices to private consumers (B2C) are not affected by the new rules.

For issuing e-invoices, the law provides transition periods. Until 31 December 2026, businesses may still send paper invoices or invoices in other electronic formats such as PDF; sending a PDF, however, requires the consent of the recipient. During 2027, this option is only available to businesses whose total turnover in the previous year did not exceed EUR 800,000. From 1 January 2028, all businesses must issue e-invoices. Invoices for small amounts of up to EUR 250 and travel tickets are exempt.

Two formats are widely used. XRechnung is a purely XML-based format; it is required by many public authorities, which use a routing ID (“Leitweg-ID”) to forward each invoice to the responsible department. ZUGFeRD is a hybrid format: a PDF/A-3 document that contains the invoice data as an embedded XML file. People can read the PDF, while software processes the XML. If the two parts differ, the XML data prevail.

The law does not prescribe a specific transmission channel. E-invoices can be sent by e-mail, uploaded to a portal, exchanged via an API or delivered through the Peppol network. In any case, they must be stored in their original format.

Selbst verfasster Text auf Grundlage der Rechtslage 2026.

Anlage 12 · Auszug aus einer erzeugten Rechnung (vereinfachtes XML-Format)

 1  <?xml version="1.0" encoding="UTF-8"?>
 2  <rechnung xmlns="urn:kranich:frischekiste:rechnung:1.0">
 3    <rechnungsnummer>RE-2026-04711</rechnungsnummer>
 4    <rechnungsdatum>2026-11-30</rechnungsdatum>
 5    <faelligAm>2026-11-16</faelligAm>
 6    <leitwegId>03359012-4711-08</leitwegId>
 7    <verkaeufer>
 8      <name>FrischeKiste Nordheide GmbH</name>
 9      <ustId>DE123456789</ustId>
10    </verkaeufer>
11    <kaeufer>
12      <name>Stadt Heidmoor, Kita Sonnenblume</name>
13    </kaeufer>
14    <position nr="1">
15      <bezeichnung>Obstkiste mittel</bezeichnung>
16      <menge>8</menge>
17      <einzelpreis>18.50</einzelpreis>
18      <nettobetrag>148.00</nettobetrag>
19      <steuersatz>7</steuersatz>
20    </position>
21    <position nr="2">
22      <bezeichnung>Gemüsekiste groß</bezeichnung>
23      <menge>4</menge>
24      <einzelpreis>27.90</einzelpreis>
25      <nettobetrag>101.60</nettobetrag>
26      <steuersatz>7</steuersatz>
27    </position>
28    <summen>
29      <nettogesamt>259.60</nettogesamt>
30      <umsatzsteuer>18.17</umsatzsteuer>
31      <bruttogesamt>278.77</bruttogesamt>
32    </summen>
33  </rechnung>

Das Dokument wurde erfolgreich gegen das zugehörige XML-Schema rechnung.xsd validiert (Datentypen: Datumsangaben xs:date, Mengen und Beträge xs:decimal). Beträge in Euro, steuersatz in Prozent; für Lebensmittel gilt der ermäßigte Steuersatz von 7 %.

C · Aufgaben

Alle Aufgaben beziehen sich auf die Ausgangssituation in Anlage 1. Algorithmen sind in Pseudocode zu entwickeln; eine Programmiersprache (z. B. Java) ist ebenfalls zulässig. Für alle Attribute stehen Get-Methoden zur Verfügung (Anlage 4).

SD-01 · XML

Aufgabe SD-01.1 ★☆☆ Grundlagen 6 Punkte

Die Fahrer-App meldet nach jeder Lieferung den Status an den Server. Ein Kollege zeigt Ihnen eine solche Statusmeldung:

 1  <?xml version="1.0" encoding="UTF-8"?>
 2  <lieferung nr="88120">
 3    <status>zugestellt</status>
 4    <zeit>2026-11-10T09:42:00</zeit>
 5    <ablage hinweis="Garage"/>
 6  </lieferung>
2 Pa) Benennen Sie die folgenden Bestandteile der Statusmeldung.
BestandteilBezeichnung
<?xml version="1.0" encoding="UTF-8"?>
das Element lieferung (Zeilen 2–6)
nr="88120"
<ablage hinweis="Garage"/>
4 Pb) Erläutern Sie die Eigenschaften „wohlgeformt“ und „gültig“ eines XML-Dokuments. Geben Sie jeweils an, ob die Statusmeldung diese Eigenschaft besitzt. Zu der Statusmeldung existiert bisher keine DTD und kein XML-Schema.
EigenschaftErläuterungtrifft auf die Statusmeldung zu?
wohlgeformt
gültig

Angelehnt an: W22 Teil 1, Aufgabe 3cb

Aufgabe SD-01.2 ★★☆ Anwendung 10 Punkte

Für die Stammdaten der Erzeugerbetriebe und für die Lieferscheine werden Strukturbeschreibungen benötigt.

4 Pa) Erläutern Sie die Bedeutung der folgenden Deklarationen aus der Strukturbeschreibung der Erzeuger-Stammdaten.
DeklarationBedeutung
<!ELEMENT erzeuger (name, telefon?, email+, hof)>
<!ELEMENT hof (adresse | koordinaten)>
<!ATTLIST erzeuger id ID #REQUIRED
                  status (aktiv|pausiert) "aktiv">
<xs:element name="zertifikat" type="xs:string"
    minOccurs="0" maxOccurs="unbounded"/>
6 Pb) Erstellen Sie die externe DTD lieferschein.dtd für den Lieferschein in Anlage 6. Es gelten folgende Regeln:
  • Ein Lieferschein enthält genau einen Kunden, danach mindestens eine Position und am Ende optional den Namen des Fahrers.
  • Lieferscheinnummer (nr) und Datum (datum) sind Pflichtattribute des Lieferscheins, die Kundennummer (kundenNr) ist Pflichtattribut des Kunden.
  • Ein Kunde hat genau einen Namen und eine Adresse.
  • Eine Position enthält genau eine Kiste und eine Anzahl, danach beliebig viele Bemerkungen (auch keine).
  • Alle übrigen Elemente enthalten nur Text.

Angelehnt an: W22 Teil 1, Aufgabe 3c (DTD lesen)

Aufgabe SD-01.3 ★★★ Prüfungsniveau 16 Punkte

Die Erzeugerbetriebe laden ihr Wochenangebot als XML-Datei im KistenPortal hoch. Bevor die Daten importiert werden, prüft das KistenPortal jede Datei gegen die externe DTD wochenangebot.dtd (Anlage 5).

2 Pa) Erläutern Sie, wofür die DTD in diesem Zusammenhang benötigt wird.
8 Pb) Das Wochenangebot von Hof Brammer für KW 46 (Anlage 5) enthält acht Fehler. Einer davon ist bereits in die Tabelle eingetragen.
Ermitteln Sie vier weitere Fehler. Geben Sie jeweils die Zeile, eine Beschreibung des Fehlers und die verletzte Eigenschaft (Wohlgeformtheit oder Gültigkeit) an.
ZeileBeschreibungEigenschaft
29Das Element lieferant ist in der DTD nicht deklariert.Gültigkeit
4 Pc) Für KW 47 lädt Hof Brammer eine Datei hoch, die gegen die DTD gültig ist. Sie enthält unter anderem folgenden Artikel:
<artikel artNr="A-110" einheit="kg">
  <bezeichnung>Grünkohl</bezeichnung>
  <menge>ca. 80</menge>
  <preis>-1.90</preis>
</artikel>
Erläutern Sie, warum diese Werte die Prüfung gegen die DTD bestehen, und beschreiben Sie zwei Maßnahmen, mit denen solche Fehler vor dem Import erkannt werden können.
2 Pd) Nennen Sie zwei Vorteile eines XML-Schemas (XSD) gegenüber einer DTD.

Angelehnt an: W22 Teil 1, Aufgabe 3c (Fehler anhand einer DTD finden) und W25 Teil 1, Aufgabe 3bc (Grenzen der Schema-Validierung)

SD-02 · JSON

Aufgabe SD-02.1 ★☆☆ Grundlagen 6 Punkte
2 Pa) Beschreiben Sie den Unterschied zwischen einem JSON-Objekt und einem JSON-Array.
4 Pb) Ein Kollege hat für einen Test das folgende Dokument geschrieben. Der JSON-Parser lehnt es ab. Das Dokument enthält vier Fehler. Geben Sie die Fehler an und korrigieren Sie sie.
1  {
2    'kisteId': "K-MIX-S",
3    "preis": 14,20,
4    "bio": False,
5    "inhalt": ["Äpfel", "Möhren", "Kartoffeln",]
6  }
ZeileFehlerKorrektur
Aufgabe SD-02.2 ★★☆ Anwendung 10 Punkte

Die Kistenarten sollen aus den bisherigen Tabellen (Anlage 7) in die dokumentenorientierte Datenbank übernommen und über die API an die App geliefert werden.

5 Pa) Überführen Sie die Tabelle Kiste in ein JSON-Dokument mit einem Array kisten. Wählen Sie für jeden Wert einen passenden JSON-Datentyp. Nutzen Sie die Syntaxbeschreibung in Anlage 10.
3 Pb) Die App soll mit einer Kiste auch deren Inhalt erhalten. Geben Sie für die Kiste K-OBST-M das Array inhalt an, das mit den Einträgen der Tabelle Kisteninhalt in das Objekt aus a) eingebettet wird.
2 Pc) Nennen Sie zwei Gründe, warum für die Kommunikation zwischen App und Server JSON statt XML verwendet wird.

Angelehnt an: W23 Teil 1, Aufgabe 3ca

Aufgabe SD-02.3 ★★★ Prüfungsniveau 20 Punkte

Auch die Kundendaten werden in die dokumentenorientierte Datenbank übernommen. Außerdem soll die Fahrer-App die offenen Stopps einer Tour als JSON erhalten.

5 Pa) Überführen Sie die Tabellen Kunde und Lieferadresse (Anlage 8) in ein JSON-Dokument mit den Arrays kunden und lieferadressen. Die Zuordnung einer Lieferadresse zu ihrem Kunden erfolgt wie bisher über die Kundennummer (Referenz).
3 Pb) Alternativ sollen die Lieferadressen in das Kundendokument eingebettet werden. Erstellen Sie das JSON-Dokument der Kundin 10427 mit eingebetteten Lieferadressen.
4 Pc) Für zwei weitere Datenbestände ist zu entscheiden, ob sie eingebettet oder referenziert werden. Entscheiden Sie jeweils begründet.
DatenbestandEmbedding oder Referenz?Begründung
(1) die Bestellungen eines Kunden: Ein Abo-Kunde sammelt über die Jahre mehrere Hundert Bestellungen; beim Öffnen des Kundenkontos zeigt die App nur Name und Lieferadressen.
(2) die Positionen einer Bestellung (Kiste, Anzahl, Preis zum Bestellzeitpunkt): Eine Bestellung hat ein bis fünf Positionen, sie werden immer mit der Bestellung angezeigt und ändern sich danach nicht mehr.
8 Pd) Entwickeln Sie die Methode offeneStoppsAlsJson(stopps : List<Stopp>) : string. Sie liefert alle noch nicht zugestellten Stopps als JSON-Array in der Reihenfolge der Liste. Jedes Objekt enthält die Schlüssel position, kundenNr, ort und kisten (Anzahl der Kisten). Gibt es keine offenen Stopps, wird [] zurückgegeben. Zeilenumbrüche und Einrückungen sind nicht erforderlich. Klasse Stopp und Hinweise zu Zeichenketten: Anlage 4.
Für die Testdaten aus Anlage 9 ergibt sich (in einer Zeile):
[{"position": 2, "kundenNr": 20015, "ort": "Heidmoor", "kisten": 6}, {"position": 3, "kundenNr": 10533, "ort": "Wiesede", "kisten": 1}, {"position": 5, "kundenNr": 20022, "ort": "Wiesede", "kisten": 4}]

Angelehnt an: W23 Teil 1, Aufgabe 3c (Tabellen in JSON, Embedding) und W24 Teil 1, Aufgabe 2c (Skript mit JSON-Ausgabe)

SD-03 · REST-Grundlagen & HTTP-Methoden

Aufgabe SD-03.1 ★☆☆ Grundlagen 6 Punkte

Die KistenPortal-API (Anlage 2) bildet die vier Grundoperationen auf Daten (CRUD) auf HTTP-Methoden ab.

4 Pa) Ergänzen Sie die Tabelle um je ein Beispiel aus dem KistenPortal und die passende HTTP-Methode.
OperationBeispiel im KistenPortalHTTP-Methode
C – Create
R – Read
U – Update
D – Delete
2 Pb) Die API ist zustandslos. Erläutern Sie, was das für die Requests der Kunden-App bedeutet.

Angelehnt an: S24 Teil 1, Aufgabe 2b

Aufgabe SD-03.2 ★★☆ Anwendung 10 Punkte

Für die nächste Version der Kunden-App werden weitere Endpunkte benötigt. Halten Sie sich an die Konventionen der API-Dokumentation (Anlage 2).

6 Pa) Geben Sie für jede Anforderung die HTTP-Methode und den Endpunkt (relativ zur Basis-URL, mit konkreten Werten) an.
Nr.AnforderungMethodeEndpunkt
1alle Bio-Kisten der Größe L anzeigen
2das Abo 5531 der Kundin 10427 bis zum 24.11.2026 pausieren (nur Status und Datum ändern)
3die Lieferadresse 2 der Kundin 10427 löschen
4eine Reklamation zur Bestellung 88120 erfassen
5die Lieferadresse 1 der Kundin 10427 vollständig durch neue Daten ersetzen
6alle Bestellungen der Kundin 10427 aus dem November 2026 anzeigen
2 Pb) Erläutern Sie an einem Beispiel aus a) den Unterschied zwischen Pfad- und Query-Parametern.
2 Pc) Die Basis-URL enthält die Angabe /v1. Erläutern Sie den Zweck dieser Angabe.
Aufgabe SD-03.3 ★★★ Prüfungsniveau 18 Punkte

Die Geschäftsführung der FrischeKiste möchte die API künftig auch weiteren Partnern anbieten und lässt sich das Konzept erklären. Gleichzeitig melden Testkunden Auffälligkeiten in der App.

3 Pa) Erläutern Sie das Konzept einer REST-API (Representational State Transfer Application Programming Interface).
5 Pb) Geben Sie für die folgenden Requests an, ob sie sicher und ob sie idempotent sind, und begründen Sie kurz.
RequestsicheridempotentBegründung
GET /v1/kisten?bio=true
POST /v1/kunden/10427/abos
(Body wie in Anlage 3)
PUT /v1/kunden/10427/abos/5531
(vollständige Repräsentation)
PATCH /v1/kunden/10427/abos/5531
{"status": "pausiert",
 "pausiertBis": "2026-11-24"}
DELETE /v1/kunden/10427/lieferadressen/2
4 Pc) Eine Testkundin tippt bei schlechtem Mobilfunkempfang auf „Abo abschließen“, erhält keine Rückmeldung und tippt erneut. Danach hat sie zwei identische Abos. Erläutern Sie die Ursache und beschreiben Sie eine Lösung.
4 Pd) Beim Abo 5531 (Anlage 2) soll der Liefertag auf Donnerstag geändert werden. Geben Sie je einen Request mit PUT und mit PATCH an (Request-Zeile und Body; Header dürfen entfallen).
2 Pe) Nennen Sie zwei Unterschiede zwischen REST und SOAP.

Angelehnt an: S24 Teil 1, Aufgabe 2a/2b und S26 Teil 1, Aufgabe 2ba/2bc

SD-04 · HTTP-Request/Response & Statuscodes

Aufgabe SD-04.1 ★☆☆ Grundlagen 6 Punkte
3 Pa) Erläutern Sie die Bedeutung der folgenden Klassen von HTTP-Statuscodes.
CodeBedeutung
2xx
4xx
5xx
2 Pb) Eine Testkundin meldet, dass die App beim Öffnen von „Meine Abos“ die Meldung „Fehler 404“ anzeigt. Nennen Sie zwei mögliche Ursachen.
1 Pc) Während eines Datenbank-Updates ist die API für 20 Minuten nicht nutzbar. Nennen Sie den Statuscode, den die API in dieser Zeit senden sollte.

Angelehnt an: S24 Teil 1, Aufgabe 2d und W21 Teil 1, Aufgabe 3c

Aufgabe SD-04.2 ★★☆ Anwendung 12 Punkte
4 Pa) Beschreiben Sie die Bedeutung der folgenden Bestandteile des Requests aus Anlage 3. Die erste Zeile ist als Beispiel ausgefüllt.
BestandteilBedeutung
POSTHTTP-Methode: legt eine neue Ressource an – hier ein neues Abo in der Sammlung der Abos der Kundin
/v1/kunden/10427/abos
Content-Type: application/json
Accept: application/json
X-API-Key: app-7Fq2-Lx91
{"kisteId": "K-GEM-L", "rhythmus": …}
b) Für die Tourenplanung ruft das KistenPortal die Web-API eines Kartendienstes auf:
GET https://api.geodienst.example/v2/route?start=53.3297,9.8722&ziel=53.2464,10.4115&profil=transporter&apikey=GD-55K2-ZZ81
3 Pba) Beschreiben Sie die Parameter der URL. Ein Beispiel ist angegeben.
ParameterBeschreibung
/v2/routedie angefragte Ressource (eine Route) in Version 2 der API
start=53.3297,9.8722
ziel=53.2464,10.4115
profil=transporter
apikey=GD-55K2-ZZ81
1 Pbb) Nennen Sie einen Nachteil, wenn der API-Schlüssel als Query-Parameter in der URL übertragen wird.
4 Pc) Geben Sie für die folgenden Situationen den passenden Statuscode an und begründen Sie Ihre Wahl.
SituationCodeBegründung
(1) Die App sendet POST /v1/kunden/10427/abos; im JSON-Body fehlt das Pflichtfeld kisteId.
(2) Ein Erzeugerbetrieb sendet mit seinem gültigen Partnerschlüssel DELETE /v1/kisten/K-MIX-S.
(3) Die Kundin löscht ihre Lieferadresse 2 erfolgreich; die Antwort enthält bewusst keinen Body.
(4) Eine veraltete App ruft /v0/kisten auf; diese Adresse wurde dauerhaft durch /v1/kisten ersetzt.

Angelehnt an: S24 Teil 1, Aufgabe 2c und S26 Teil 1, Aufgabe 2bb

Aufgabe SD-04.3 ★★★ Prüfungsniveau 20 Punkte

Sie implementieren in der Klasse KistenController (Anlage 4) den Endpunkt GET /v1/kisten/{kisteId}. Der Pfadparameter heißt kisteId.

8 Pa) Entwickeln Sie die Methode createErrorResponse(statusCode : integer, meldung : string) : HttpResponse. Die erzeugte Antwort enthält
  • den übergebenen Statuscode,
  • den Header Content-Type mit dem Wert application/json; charset=utf-8,
  • den Header Content-Length mit der Anzahl der Bytes des Bodys,
  • als Body: {"status": <statusCode>, "fehler": "<meldung>"} – genau in dieser Schreibweise, also mit je einem Leerzeichen nach Doppelpunkt und Komma.
Beispiel für Statuscode 404 und die Meldung „Kiste K-XXL-Z nicht gefunden“:
HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Content-Length: 57

{"status": 404, "fehler": "Kiste K-XXL-Z nicht gefunden"}
3 Pb) Ein Kollege berechnet den Wert von Content-Length mit body.length(). Erläutern Sie, warum das zu falschen Werten führen kann. Geben Sie für die Fehlerantwort mit dem Statuscode 503 und der Meldung „Katalog vorübergehend nicht verfügbar“ die Anzahl der Zeichen des Bodys und den korrekten Wert von Content-Length an.
9 Pc) Entwickeln Sie die Methode handleGetKiste(request : HttpRequest) : HttpResponse. Sie prüft in dieser Reihenfolge:
  1. Fehlt der Header X-API-Key oder ist der Schlüssel ungültig: Statuscode 401, Meldung „API-Schlüssel fehlt oder ist ungültig“.
  2. Ist der Katalog nicht verfügbar: Statuscode 503, Meldung „Katalog vorübergehend nicht verfügbar“.
  3. Gibt es keine Kiste mit der kisteId aus dem Pfad: Statuscode 404, Meldung „Kiste <kisteId> nicht gefunden“.
  4. Andernfalls: Statuscode 200, Body = JSON-Repräsentation der Kiste, Header Content-Type und Content-Length wie in a).
Verwenden Sie für die Fehlerfälle die Methode aus a).

Angelehnt an: W24 Teil 2, Aufgabe 2a (HTTP-Antwort mit Statuscode, Content-Type und Content-Length bauen)

SD-05 · eRechnung

Aufgabe SD-05.1 ★☆☆ Grundlagen 6 Punkte
2 Pa) Erläutern Sie das Hauptziel einer eRechnung.
4 Pb) Entscheiden Sie für die folgenden Rechnungen der FrischeKiste, ob es sich um eine eRechnung im Sinne der EN 16931 handelt, und begründen Sie kurz.
RechnungeRechnung?Begründung
(1) in der Textverarbeitung geschrieben, als PDF per E-Mail an eine Kantine geschickt
(2) XRechnung im UBL-Format, im Rechnungsportal der Stadt Heidmoor hochgeladen
(3) Papierrechnung, eingescannt und als JPG-Bild per E-Mail verschickt
(4) ZUGFeRD-Rechnung im Profil EN 16931, per E-Mail an ein Büro geschickt

Angelehnt an: W25 Teil 1, Aufgabe 2ba

Aufgabe SD-05.2 ★★☆ Anwendung 10 Punkte

Die Geschäftsführung der FrischeKiste möchte wissen, was die eRechnungspflicht für das Unternehmen bedeutet. Sie haben den englischen Text in Anlage 11 gefunden. Beantworten Sie die Fragen auf Deutsch.

3 Pa) Beschreiben Sie anhand des Textes, ab wann Unternehmen in Deutschland eRechnungen empfangen und ab wann sie eRechnungen ausstellen müssen.
4 Pb) Erläutern Sie den Unterschied zwischen den Formaten XRechnung und ZUGFeRD.
3 Pc) Die FrischeKiste verschickt ihre Rechnungen bisher an Geschäfts- und an Privatkunden als PDF per E-Mail. Beurteilen Sie mithilfe des Textes und der Angaben in Anlage 1, ob das im Jahr 2027 noch zulässig ist.

Angelehnt an: W25 Teil 1, Aufgabe 2b (englischer Fachtext zur eRechnung)

Aufgabe SD-05.3 ★★★ Prüfungsniveau 18 Punkte

Die Kranich Softwarehaus GmbH entwickelt das Modul, das aus den Bestellungen eRechnungen erzeugt. Die Stadt Heidmoor verlangt für ihre Kitas und Schulen XRechnungen mit Leitweg-ID. Die Rechnungen an Geschäftskunden sollen per E-Mail versendet werden.

3 Pa) Damit die Empfänger die Rechnungen zuverlässig verarbeiten können, müssen die erzeugten Dateien der Spezifikation entsprechen. Nennen Sie drei Möglichkeiten, wie Sie dies sicherstellen können.
4 Pb) Ein Kollege möchte die ersten echten Rechnungen auf der kostenlosen Website www.erechnung-check.example prüfen lassen. Dort lädt man eine Rechnung hoch und erhält ein Prüfergebnis. Erläutern Sie zwei Punkte, die bei der Nutzung zu beachten sind.
6 Pc) Die Rechnung in Anlage 12 wurde erfolgreich gegen das XML-Schema validiert. Erläutern Sie anhand von zwei Fehlern in Anlage 12 (mit Zeilenangabe), warum eine ausschließliche Schema-Validierung nicht ausreicht.
d) Für den Versand per E-Mail nutzen die beteiligten Mailserver eine Transportverschlüsselung mit TLS.
1 Pda) Nennen Sie die Art des Verschlüsselungsverfahrens, auf der TLS beruht.
2 Pdb) Erläutern Sie, warum die Rechnung trotz TLS nicht Ende-zu-Ende geschützt ist, und nennen Sie eine Alternative.
2 Pe) Erläutern Sie den Zweck der Leitweg-ID (Anlage 12, Zeile 6).

Angelehnt an: W25 Teil 1, Aufgabe 3a und 3b

Originalaufgaben zum Üben

Diese echten Prüfungsaufgaben passen zu diesem Block (Dateien im Ordner Prüfungsvorbereitung). Lösungen gibt es nur für 2023 Sommer, 2023 Winter, 2024 Sommer und 2025 Winter (dort vom u-form-Verlag).

PrüfungAufgabeThemaDatei · Lösung
Winter 2021T1 A3c (2 P)Ursache für HTTP-Fehler 4042021/winter/AE 2021 Winter Teil 1.pdf · keine Lösung
Winter 2022T1 A3c (13 P)XML: Zweck der DTD, wohlgeformt/gültig, Fehler anhand der DTD finden2022/winter/AE 2022 Winter Teil 1.pdf · keine Lösung
Sommer 2023T1 A4cb (13 P)Relationenmodell in 3NF inkl. JSON-Sensordaten2023/sommer/AE Sommer 2023 Teil 1.pdf · Lösung: AE Sommer 2023 Teil 1+2 Lösungen.pdf
Winter 2023T1 A3c (14 P)Tabellen in JSON überführen, Verkaufsstellen als Array einbetten2023/winter/AE Winter 2023 Teil 1.pdf · Lösung: AE Winter 2023 Teil 1 Lösungen.pdf
Sommer 2024T1 A2 (25 P)REST-Konzept, CRUD/HTTP-Methoden, Request-Bestandteile, Statuscodes, Sequenzdiagramm App/WebService/DB2024/sommer/AE Sommer 2024 Teil 1+2+3.pdf · Lösung: AE Sommer 2024 Teil 1 Lösungen.pdf
Winter 2024T1 A2c (8 P)Skript: Subnetz durchlaufen, Ergebnis als JSON-Array2024/winter/AE Winter 2024 Teil 1.pdf · keine Lösung
Winter 2024T2 A2a (10 P)HttpResponse mit Statuscode, Content-Type und Content-Length bauen2024/winter/AE Winter 2024 Teil 2.pdf · keine Lösung
Winter 2025T1 A2b (9 P)eRechnung: englischer Text, Hauptziel, Aspekte einer digitalen Rechnung2025/winter/AE Winter 2025 Teil 1.pdf · Lösung: AE Winter 2025 Lösungserleuterungen.pdf (u-form)
Winter 2025T1 A3a, A3b (19 P)Transportverschlüsselung, Konformität, Online-Prüfseite, XSD-Validierung reicht nichtwie oben
Sommer 2026T1 A2b (12 P)REST-Konzept, Parameter einer GET-URL, weitere HTTP-Methoden2026/sommer/AE Sommer 2026 Teil 1.pdf · keine Lösung