from lxml import etree import re W_TAGS = ['w'] C_TAGS = ['c'] S_TAGS = ['S', 'pc'] # reads a TEI xml file and returns a dictionary: # { : { # sid: , # serves as index in MongoDB # text: , # tokens: , # }} def parse_tei(filepath): guess_corpus = None # SSJ | KRES res_dict = {} with open(filepath, "r") as fp: # remove namespaces xmlstr = fp.read() xmlstr = re.sub('\\sxmlns="[^"]+"', '', xmlstr, count=1) xmlstr = re.sub(' xml:', ' ', xmlstr) root = etree.XML(xmlstr.encode("utf-8")) divs = [] # in ssj, there are divs, in Kres, there are separate files if "id" in root.keys(): # Kres files start with guess_corpus = "KRES" divs = [root] else: guess_corpus = "SSJ" divs = root.findall(".//div") # parse divs for div in divs: f_id = div.get("id") # parse paragraphs for p in div.findall(".//p"): p_id = p.get("id").split(".")[-1] # parse sentences for s in p.findall(".//s"): s_id = s.get("id").split(".")[-1] sentence_text = "" sentence_tokens = [] # parse tokens for el in s.iter(): if el.tag in W_TAGS: el_id = el.get("id").split(".")[-1] if el_id[0] == 't': el_id = el_id[1:] # ssj W_TAG ids start with t sentence_text += el.text sentence_tokens += [( "w", el_id, el.text, el.get("lemma"), (el.get("msd") if guess_corpus == "KRES" else el.get("ana").split(":")[-1]), )] elif el.tag in C_TAGS: # only Kres' C_TAGS have ids el_id = el.get("id") or "none" el_id = el_id.split(".")[-1] sentence_text += el.text sentence_tokens += [("c", el_id, el.text,)] elif el.tag in S_TAGS: # Kres' doesn't contain .text sentence_text += " " else: # pass links and linkGroups # print(el.tag) pass sentence_id = "{}.{}.{}".format(f_id, p_id, s_id) """ print(sentence_id) print(sentence_text) print(sentence_tokens) """ if sentence_id in res_dict: raise KeyError("duplicated id: {}".format(sentence_id)) res_dict[sentence_id] = { "sid": sentence_id, "text": sentence_text, "tokens": sentence_tokens } return res_dict def msd_slo_to_ang(msd): # mapping table: http://nl.ijs.si/imp/msd/html-sl/#msd.index.values # 3.1.1: list of POS # 3.3.1: list of values msd = "Sosei" def slo_pos(msd): return msd[0] def pos_slo_ang_map(col, query): pos_slo_ang = [ ("samostalnik", "S", "Noun", "N"), ("glagol", "G", "Verb", "V"), ("pridevnik", "P", "Adjective", "A"), ("prislov", "R", "Adverb", "R"), ("zaimek", "Z", "Pronoun", "P"), ("števnik", "K", "Numeral", "M"), ("predlog", "D", "Preposition", "S"), ("veznik", "V", "Conjunction", "C"), ("členek", "L", "Particle", "Q"), ("medmet", "M", "Interjection", "I"), ("okrajšava", "O", "Abbreviation", "Y"), ("neuvrščeno", "N", "Residual", "X"), ] for pos in pos_slo_ang: if pos[col] == query: return pos raise ValueError("Wrong part of speech.") def pos_val_map(col, query): # col: # (sl_vrednost, sl_koda, sl_atribut, sl_kategorija, # en_vrednost, en_koda, en_atribut, en_kategorija) pos_val = [ ("arabski", "a", "zapis", "števnik", "digit", "d", "Form", "Numeral"), ("besedni", "b", "zapis", "števnik", "letter", "l", "Form", "Numeral"), ("deležje", "d", "vrsta", "prislov", "participle", "r", "Type", "Adverb"), ("deležniški", "d", "vrsta", "pridevnik", " participle", "p", "Type", "Adjective"), ("dovršni", "d", "vid", "glagol", " perfective", "e", "Aspect", "Verb"), ("dvovidski", "v", "vid", "glagol", " biaspectual", "b", "Aspect", "Verb"), ("glavni", "g", "vrsta", "glagol", " main", "m", "Type", "Verb"), ("lastno_ime", "l", "vrsta", "samostalnik", "proper", "p", "Type", "Noun"), ("moški", "m", "spol", "samostalnik", "masculine", "m", "Gender", "Noun"), ("nedoločeno", "n", "stopnja", "pridevnik", " positive", "p", "Degree", "Adjective"), ("nedoločeno", "n", "stopnja", "prislov", "positive", "p", "Degree", "Adverb"), ("nedovršni", "n", "vid", "glagol", " progressive", "p", "Aspect", "Verb"), ("občno_ime", "o", "vrsta", "samostalnik", "common", "c", "Type", "Noun"), ("pomožni", "p", "vrsta", "glagol", " auxiliary", "a", "Type", "Verb"), ("presežnik", "s", "stopnja", "pridevnik", " superlative", "s", "Degree", "Adjective"), ("presežnik", "s", "stopnja", "prislov", "superlative", "s", "Degree", "Adverb"), ("primernik", "p", "stopnja", "pridevnik", " comparative", "c", "Degree", "Adjective"), ("primernik", "r", "stopnja", "prislov", "comparative", "c", "Degree", "Adverb"), ("program", "p", "vrsta", "neuvrščeno", " program", "p", "Type", "Residual"), ("rimski", "r", "zapis", "števnik", "roman", "r", "Form", "Numeral"), ("splošni", "p", "vrsta", "pridevnik", " general", "g", "Type", "Adjective"), ("splošni", "s", "vrsta", "prislov", "general", "g", "Type", "Adverb"), ("srednji", "s", "spol", "samostalnik", "neuter", "n", "Gender", "Noun"), ("svojilni", "s", "vrsta", "pridevnik", " possessive", "s", "Type", "Adjective"), ("tipkarska", "t", "vrsta", "neuvrščeno", " typo", "t", "Type", "Residual"), ("tujejezično", "j", "vrsta", "neuvrščeno", " foreign", "f", "Type", "Residual"), ("ženski", "z", "spol", "samostalnik", "feminine", "f", "Gender", "Noun"), ] for pos in pos_val: if pos[col] == query: return pos raise ValueError("Wrong part of speech value.")