xml to apkg

Xml To Apkg May 2026

1. Define the Source XML (data.xml)

<dictionary>
    <entry>
        <word>Apple</word>
        <definition>A round fruit with red or green skin.</definition>
        <image>apple.jpg</image>
    </entry>
    <entry>
        <word>Banana</word>
        <definition>A long curved fruit with yellow skin.</definition>
        <image>banana.jpg</image>
    </entry>
</dictionary>

2. The Python Script

import xml.etree.ElementTree as ET
import genanki
import random
import hashlib
# 1. Define the Note Model (The Template)
# We use a hardcoded ID so the model stays consistent across runs.
def get_model_id():
    return 1607392319
my_model = genanki.Model(
    get_model_id(),
    'Simple XML Vocabulary Model',
    fields=[
        'name': 'Word',
        'name': 'Definition',
        'name': 'Image', # Field for media
    ],
    templates=[
'name': 'Card 1',
            'qfmt': 'Word<br>Image', # Front of card
            'afmt': 'FrontSide<hr id="answer">Definition', # Back of card
        ,
    ],
    css='.card  font-family: arial; font-size: 20px; text-align: center; color: black; background-color: white; '
)
# 2. Define the Deck
def get_deck_id():
    return random.randrange(1 << 30, 1 << 31)
my_deck = genanki.Deck(
    get_deck_id(),
    'XML Imported Vocabulary'
)
# 3. Parse the XML
def parse_xml_and_populate_deck(xml_file, deck, model):
    tree = ET.parse(xml_file)
    root = tree.getroot()
# List to hold media files for packaging later
    media_files = []
for entry in root.findall('entry'):
        word = entry.find('word').text
        definition = entry.find('definition').text
        image_filename = entry.find('image').text
# Anki requires specific formatting for images in fields
        # We construct the HTML string
        image_html = f'<img src="image_filename">'
# Add image path to media list (assuming images are in the local directory)
        media_files.append(image_filename)
# Create the Note
        # genanki handles GUIDs automatically, but manual creation ensures stability
        note = genanki.Note(
            model=model,
            fields=[word, definition, image_html]
        )
deck.add_note(note)
return media_files
# 4. Execute and Package
media_files = parse_xml_and_populate_deck('data.xml', my_deck, my_model)
# Create the package
# If you have media, you pass them in the media_files list
my_package = genanki.Package(my_deck, media_files=media_files)
# Write to file
my_package.write_to_file('output.apkg')
print("Successfully created output.apkg")

Create xml_to_csv.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" encoding="UTF-8"/>
  <xsl:template match="/cards">
    <xsl:text>Question,Answer
</xsl:text>
    <xsl:for-each select="card">
      <xsl:value-of select="question"/>
      <xsl:text>,</xsl:text>
      <xsl:value-of select="answer"/>
      <xsl:text>
</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Run transformation (using Saxon or xsltproc): xml to apkg

xsltproc xml_to_csv.xsl input.xml > output.csv
pip install genanki

anki_url = "http://localhost:8765"

for item in root.findall('card'): note = "action": "addNote", "version": 6, "params": "note": "deckName": "MyXMLDeck", "modelName": "Basic", "fields": "Front": item.find('question').text, "Back": item.find('answer').text , "tags": ["xml_import"] requests.post(anki_url, data=json.dumps(note)) Create xml_to_csv

After execution, your cards appear instantly in Anki. You can then export as .apkg via the GUI. "params": "note": "deckName": "MyXMLDeck"