Parse XML output from Rest API?

My object is to display the next 4 departures from a local bus stop.
The transit authority publicizes this data openly in XML format.

Here’s an example URL, it does not require any API key or registration

It displays the next departures from a given bus stop. Line.Name is the bus/train line name, JourneyDateTime is the departure time. Towards is where it’s heading. RealTimeInfo.DepTimeDeviation is added time in minutes if the bus is late.

There is a previous thread on this topic, but it is a really simple example grabbing only one tag from the XML. In my case the XML data is larger and has sub-keys and so on.

What would be the best method of parsing the API XML output and displaying it in the Home Assistant UI?
I’ve successfully parsed the XML with PowerShell since I’m familiar with that language, but for Python or Bash I don’t really know where to begin.
Any ideas?

I suggest you use a command line sensor and call a python script. In python you can access the XML. Like here


1 Like

Thanks I’ll look into that, there was some nice examples too.

What would be the best method to display multi-row table output in Home Assistant?
Most output is configured as single sensor, single value.

In this case I’d like to somehow display, let’s say the four next departures, something like this:

Time Bus Destination

15:34 2 Somewhere Mall
15:55 4 Worlds end
16:23 5 Home

That is something I have with struggling myself. I ended up doing 5 sensors in my case. I don’t know how text_inputs get displayed but maybe they could work as well with a “\n” character.


1 Like

Hey @tompat did you get anywhere with this? Is there any code you care to share with a newbie in HA?


Since there’s no good resources how to go about this I’m using this approach

Query exampleöjelgatan 6 Malmö&inpPointTo=Malmö Triangeln

# Name|Id|Type
Flöjelgatan 6 Malmö|378074|1 #home address to search nearest stations
Malmö Triangeln|80140|0 # destination
skanetrafiken: |-
  api=$(curl -s '|378074|1&selPointTo=Malm%C3%B6%20Triangeln|80140|0'); 
  tid=$(echo $api | sed -e 's,.*<DepDateTime>\([^<]*\)</DepDateTime>.*,\1,g' | cut -d T -f2 | cut -d ':' -f1,2); 
  plats=$(echo $api | sed -n 's:.*<Name>\(.*\)</Name><StopPoint>B</StopPoint></From>.*:\1:p' | cut -d\  -f2); 
  echo $tid 'från' $plats
# sensor
- platform: command_line
  name: skanetrafiken
  scan_interval: 120
  command: !secret skanetrafiken

Using xmllint to get multiple departures, not sure how you would get that into hass, but I’m only using the first example anyways.


# xmllint
api=$(curl -s '|378074|1&selPointTo=Malm%C3%B6%20Triangeln|80140|0'); 
tid1=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[1]/RouteLinks/RouteLink[2]/DepDateTime/text())' - | cut -d T -f2 | cut -d ':' -f1,2); 
plats1=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[1]/RouteLinks/RouteLink[2]/From/Name/text())' - | cut -d\  -f2); 
tid2=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[2]/RouteLinks/RouteLink[2]/DepDateTime/text())' - | cut -d T -f2 | cut -d ':' -f1,2); 
plats2=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[2]/RouteLinks/RouteLink[2]/From/Name/text())' - | cut -d\  -f2); 
tid3=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[3]/RouteLinks/RouteLink[2]/DepDateTime/text())' - | cut -d T -f2 | cut -d ':' -f1,2); 
plats3=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[3]/RouteLinks/RouteLink[2]/From/Name/text())' - | cut -d\  -f2); 
tid4=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[4]/RouteLinks/RouteLink[2]/DepDateTime/text())' - | cut -d T -f2 | cut -d ':' -f1,2); 
plats4=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[4]/RouteLinks/RouteLink[2]/From/Name/text())' - | cut -d\  -f2); 
tid5=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[5]/RouteLinks/RouteLink[2]/DepDateTime/text())' - | cut -d T -f2 | cut -d ':' -f1,2); 
plats5=$(echo $api | sed -e 's/xmlns=".*"//g' | xmllint --xpath 'string(//Journeys/Journey[5]/RouteLinks/RouteLink[2]/From/Name/text())' - | cut -d\  -f2); 
echo $tid1 'från' $plats1; echo $tid2 'från' $plats2; echo $tid3 'från' $plats3; echo $tid4 'från' $plats4; echo $tid5 'från' $plats5

This seems interesting