XML Parser

I've worked on the code and now I need your help once more :slight_smile:
The download of the data works perfect, also the output on the LED Matrix (as you can see in the photos).

When I just download one row of data (http://www.ivb.at/smartinfo/ivb_smartinfo_kernel.php?olifServerId=84&autorefresh=20&default_autorefresh=20&routeId=&stopId=Absam%20Dorf&optDir=-1&nRows=1&showArrivals=n&optTime=now&time=&allLines=y&app=sionline) the matrix displays everything correct (Photo 1).

But when I download 4 rows of data (as originally planned) (http://www.ivb.at/smartinfo/ivb_smartinfo_kernel.php?olifServerId=84&autorefresh=20&default_autorefresh=20&routeId=&stopId=Absam%20Dorf&optDir=-1&nRows=4&showArrivals=n&optTime=now&time=&allLines=y&app=sionline), the data is printed in one row on the matrix and not in four rows (Photo2).

Has anyone an idea how I could 'split' the four strings?

BTW the code:

#include <SPI.h>
#include <string.h>
#include <Ethernet.h>
#include "HT1632.h"

#define MAX_STRING_LEN  20
#define DATA 2
#define WR   3
#define CS   4
#define CS2  5
#define CS3  6
#define CS4  7

HT1632LEDMatrix matrix = HT1632LEDMatrix(DATA, WR, CS, CS2, CS3, CS4);

char tagStr[MAX_STRING_LEN] = "";
char dataStr[MAX_STRING_LEN] = "";
char tmpStr[MAX_STRING_LEN] = "";
char endTag[3] = {
  '<', '/', '\0'};
int len;

boolean tagFlag = false;
boolean dataFlag = false;

byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0D, 0x52, 0xBD };
byte ip[] = { 
  192, 168, 2, 3 };
byte server[] = { 
  83, 175, 126, 90 };

EthernetClient client;

void setup()
{
  Serial.begin(9600);
  matrix.begin(HT1632_COMMON_16NMOS);
  Serial.println("Starting IVB.at");
  Serial.println("connecting...");
  Ethernet.begin(mac, ip);
  delay(0);

  if (client.connect(server, 80)) {
    Serial.println("connected");
    client.println("GET /smartinfo/ivb_smartinfo_kernel.php?olifServerId=84&autorefresh=20&default_autorefresh=20&routeId=&stopId=Absam%20Dorf&optDir=-1&nRows=4&showArrivals=n&optTime=now&time=&allLines=y&app=sionline HTTP/1.0");    
    client.println("Host: www.ivb.at");  
    client.println();
    delay(10);
  } 
  else {
    Serial.println("connection failed");
    matrix.clearScreen(); 
    matrix.setTextSize(1);
    matrix.setTextColor(1);
    {
      matrix.setCursor(0, 0);
      matrix.print("Bitte   beachten");
      matrix.setCursor(0, 8);
      matrix.print("Fahrplan");
      matrix.writeScreen();
    }
    delay(100);
  }  
}

void loop() {

  // Read serial data in from web:
  while (client.available()) {
    serialEvent(); 
  }

  if (!client.connected()) {
    //Serial.println();
    //Serial.println("Disconnected");
    client.stop();

    // Time until next update
    //Serial.println("Waiting");
    for (int t = 1; t <= 15; t++) {
      delay(1000); // 1 minute
    }

    if (client.connect(server, 80)) {
      //Serial.println("Reconnected");
      client.println("GET /smartinfo/ivb_smartinfo_kernel.php?olifServerId=84&autorefresh=20&default_autorefresh=20&routeId=&stopId=Absam%20Dorf&optDir=-1&nRows=4&showArrivals=n&optTime=now&time=&allLines=y&app=sionline HTTP/1.0");    
      client.println("Host: www.ivb.at");
      matrix.clearScreen();  
      client.println();
      delay(0);
    } 
    else {
      Serial.println("Reconnect failed");
    }       
  }
}

// Process each char from web
void serialEvent() {

  // Read a char
  char inChar = client.read();
  //Serial.print(".");

  if (inChar == '<') {
    addChar(inChar, tmpStr);
    tagFlag = true;
    dataFlag = false;

  } 
  else if (inChar == '>') {
    addChar(inChar, tmpStr);

    if (tagFlag) {      
      strncpy(tagStr, tmpStr, strlen(tmpStr)+1);
    }

    // Clear tmp
    clearStr(tmpStr);

    tagFlag = false;
    dataFlag = true;      

  } 
  else if (inChar != 10) {
    if (tagFlag) {
      // Add tag char to string
      addChar(inChar, tmpStr);

      // Check for </XML> end tag, ignore it
      if ( tagFlag && strcmp(tmpStr, endTag) == 0 ) {
        clearStr(tmpStr);
        tagFlag = false;
        dataFlag = false;
      }
    }

    if (dataFlag) {
      // Add data char to string
      addChar(inChar, dataStr);
    }
  }  

  // If a LF, process the line
  if (inChar == 10 ) {

    /*
      Serial.print("routeStr: ");
     Serial.println(directionStr);
     Serial.print("directionStr: ");
     Serial.println(directionStr);
     */

    // Find specific tags and print data
    if (matchTag("<time>")) {
      Serial.print(" Abfahrt: ");
      Serial.print(dataStr);
      String stringOne = dataStr;
      Serial.println(stringOne);
      String stringTwo = stringOne;
      stringTwo.replace("min","'");
      stringTwo.replace(":","");
      matrix.setTextSize(1);
      matrix.setTextColor(1);
      {
        matrix.setCursor(24, 0);
        matrix.println(stringTwo);
        matrix.writeScreen();
      }

    }
    if (matchTag("<direction>")) {
      Serial.print(" Ziel: ");
      Serial.print(dataStr);
      String reportString = dataStr;
      char mostSignificantDigit = reportString.charAt(0);
      matrix.setTextSize(1);
      matrix.setTextColor(1);
      {
        matrix.setCursor(16, 0);
        matrix.println(mostSignificantDigit);
        matrix.writeScreen();
      }
    }
    if (matchTag("<route>")) {
      Serial.print(" Linie: ");
      Serial.print(dataStr); 
      matrix.setTextSize(1);
      matrix.setTextColor(1);
      {
        matrix.setCursor(0, 0);
        matrix.print(dataStr);
        matrix.writeScreen();
      }
      }
      
    // Clear all strings
    clearStr(tmpStr);
    clearStr(tagStr);
    clearStr(dataStr);

    // Clear Flags
    tagFlag = false;
    dataFlag = false;
  }
}

/////////////////////
// Other Functions //
/////////////////////

// Function to clear a string
void clearStr (char* str) {
  int len = strlen(str);
  for (int c = 0; c < len; c++) {
    str[c] = 0;
  }
}

//Function to add a char to a string and check its length
void addChar (char ch, char* str) {
  char *tagMsg  = "<TRUNCATED_TAG>";
  char *dataMsg = "-TRUNCATED_DATA-";

  // Check the max size of the string to make sure it doesn't grow too
  // big.  If string is beyond MAX_STRING_LEN assume it is unimportant
  // and replace it with a warning message.
  if (strlen(str) > MAX_STRING_LEN - 2) {
    if (tagFlag) {
      clearStr(tagStr);
      strcpy(tagStr,tagMsg);
    }
    if (dataFlag) {
      clearStr(dataStr);
      strcpy(dataStr,dataMsg);
    }

    // Clear the time buffer and flags to stop current processing 
    clearStr(tmpStr);
    tagFlag = false;
    dataFlag = false;

  } 
  else {
    // Add char to string
    str[strlen(str)] = ch;
  }
}

// Function to check the current tag for a specific string
boolean matchTag (char* searchTag) {
  if ( strcmp(tagStr, searchTag) == 0 ) {
    return true;
  } 
  else {
    return false;
  }
}

Thanks!

Edit: as result, it should look like in Photo 3!