#!/usr/bin/env catnip
# Parsing XML avec xml.etree.ElementTree
# Module stdlib pour lire et naviguer dans des documents XML
ET = import('xml.etree.ElementTree')
# Modélisation des données
struct Book {
id; title; author; year; category;
display(self) => {
f"Book#{self.id} '{self.title}' ({self.author}, {self.year}) [{self.category}]"
}
}
# Extraction d'un Book depuis un élément XML
book_from_xml = (node) => {
try {
Book(
node.get('id'),
node.find('title').text,
node.find('author').text,
node.find('year').text,
node.get('category'),
)
} except {
_ => { None }
}
}
# Données XML
xml_string = '<?xml version="1.0"?>
<catalog>
<book id="1" category="fiction">
<title>The Great Gatsby</title>
<author>F. Scott Fitzgerald</author>
<year>1925</year>
</book>
<book id="2" category="science">
<title>A Brief History of Time</title>
<author>Stephen Hawking</author>
<year>1988</year>
</book>
<book id="3" category="fiction">
<title>1984</title>
<author>George Orwell</author>
<year>1949</year>
</book>
</catalog>
'
# XML malformé
print("⇒ XML malformé")
try {
ET.fromstring("<broken><no-close>")
} except {
e: RuntimeError => { print(f" Attrapé: {e}") }
}
# Parsing
print()
print("⇒ Parsing XML")
root = ET.fromstring(xml_string)
print(f" Tag racine: {root.tag}")
print(f" Nombre d'enfants: {len(root)}")
# Conversion en structs
print()
print("⇒ Conversion en structs Book")
books = list()
for node in root {
book = book_from_xml(node)
if book != None {
books = books + list(book)
}
}
for book in books {
print(f" {book}")
}
# Filtrage par catégorie avec match
print()
print("⇒ Filtrage par catégorie (match)")
for book in books {
label = match book.category {
'fiction' => { "Roman" }
'science' => { "Science" }
_ => { "Autre" }
}
print(f" [{label}] {book.title}")
}
# Recherche avec findall
print()
print("⇒ Recherche avec findall")
titles = root.findall('.//title')
print(" Tous les titres:")
for t in titles {
print(f" - {t.text}")
}
# Attributs
print()
print("⇒ Attributs")
for node in root {
attrs = node.attrib
print(f" Book: {attrs}")
}
# Navigation dans l'arbre
print()
print("⇒ Navigation dans l'arbre")
for node in root {
book = book_from_xml(node)
print(f" Book id:{book.id}")
print(f" Titre: {book.title}")
print(f" Auteur: {book.author}")
}
# Livres par décennie via broadcasting
print()
print("⇒ Livres par décennie")
decades = books.[(b) => {
decade = int(b.year) - int(b.year) % 10
f" {b.title} → {decade}s"
}]
for d in decades {
print(d)
}