Technology January 20, 2026 10 min read

XMLTV Format: Structure, Fields, Examples

Technical guide to XMLTV format — the de facto standard for EPG data transfer in IPTV and OTT systems.

What is XMLTV

XMLTV is an open XML format for describing television schedules. Developed in 1999 for the xmltv.org project and became the de facto standard for IPTV middleware, media players and EPG grabbers.

Wide Support

Kodi, VLC, Ministra, Xtream and more

📖

Human Readable

Easy to read and debug

🔧

Extensible

Custom attributes and fields

Simple Parsing

Standard XML libraries

Document Structure

An XMLTV document consists of a root tv element containing lists of channels and programs:

XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE tv SYSTEM "xmltv.dtd">
<tv source-info-name="EPG Service" generator-info-name="epgservice.tv">
  
  <!-- Channel list -->
  <channel id="bbc-one">
    <display-name>BBC One</display-name>
    <icon src="https://cdn.epgservice.tv/logos/bbc-one.png"/>
  </channel>
  
  <!-- Programs -->
  <programme start="20260206180000 +0000" channel="bbc-one">
    <title lang="en">BBC News at Six</title>
    <desc lang="en">The latest national and international news</desc>
    <category lang="en">News</category>
  </programme>
  
</tv>

Channel Element

Describes a TV channel. Must come before programme elements.

Element Required Description
id (attribute) Yes Unique channel identifier
display-name Yes Channel name
icon No Channel logo URL
url No Channel website
XML — channel
<channel id="bbc-two">
  <display-name lang="en">BBC Two</display-name>
  <display-name lang="ru">Би-би-си 2</display-name>
  <icon src="https://cdn.epgservice.tv/logos/bbc-two.png"/>
  <url>https://www.bbc.co.uk/bbctwo</url>
</channel>

Programme Element

Describes one program in the schedule. Required attributes: start, channel.

XML — programme (full example)
<programme start="20260206200000 +0000" stop="20260206220000 +0000" channel="bbc-one">
  <title lang="en">Graham Norton Show</title>
  <sub-title lang="en">Guest — John Smith</sub-title>
  <desc lang="en">Entertainment talk show</desc>
  
  <credits>
    <presenter>Graham Norton</presenter>
    <guest>John Smith</guest>
  </credits>
  
  <date>2026</date>
  <category lang="en">Talk show</category>
  <language>en</language>
  <length units="minutes">120</length>
  <icon src="https://cdn.epgservice.tv/posters/norton.jpg"/>
  <country>GB</country>
  
  <episode-num system="onscreen">S20E24</episode-num>
  
  <rating system="UK">
    <value>12</value>
  </rating>
</programme>
💡

Tip

The stop attribute is optional, but recommended for correct display in grid interfaces.

Time Format

Time in XMLTV is specified in format YYYYMMDDHHmmss +HHMM:

Examples
20260206180000 +0000  → February 6, 2026, 18:00 UTC
20260206130000 -0500  → Same time in EST

Structure

  • YYYY — year (4 digits)
  • MM — month (01-12)
  • DD — day (01-31)
  • HH — hour (00-23)
  • mm — minutes (00-59)
  • ss — seconds (00-59)

Timezone

  • +HHMM — offset from UTC
  • +0000 — UTC
  • +0300 — Moscow (MSK)
  • -0500 — EST (USA)

Parsing XMLTV

Python

Python
import xml.etree.ElementTree as ET
from datetime import datetime

tree = ET.parse('epg.xml')
root = tree.getroot()

# Channels
channels = {}
for channel in root.findall('channel'):
    channel_id = channel.get('id')
    name = channel.find('display-name').text
    channels[channel_id] = name

# Programs
for programme in root.findall('programme'):
    channel_id = programme.get('channel')
    start = programme.get('start')
    title = programme.find('title').text
    
    start_dt = datetime.strptime(start[:14], '%Y%m%d%H%M%S')
    print(f"{channels[channel_id]}: {start_dt} - {title}")

JavaScript

JavaScript
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(xmlString, 'text/xml');

// Channels
const channels = {};
xmlDoc.querySelectorAll('channel').forEach(ch => {
  const id = ch.getAttribute('id');
  const name = ch.querySelector('display-name').textContent;
  channels[id] = name;
});

// Programs  
xmlDoc.querySelectorAll('programme').forEach(prog => {
  const channelId = prog.getAttribute('channel');
  const start = prog.getAttribute('start');
  const title = prog.querySelector('title').textContent;
  
  console.log(channels[channelId] + ': ' + start + ' - ' + title);
});

Validation

Use the official DTD schema to validate XMLTV:

Terminal
xmllint --dtdvalid xmltv.dtd epg.xml

Need an XMLTV file?

EPG Service provides XMLTV exports for 4308 channels. JSON API also available for modern integrations.

Get Access