forked from kristjan/cjvt-srl-tagging
189 lines
7.4 KiB
Python
189 lines
7.4 KiB
Python
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:
|
|
# { <sentence_id>: {
|
|
# sid: <sentence_id>, # 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 <TEI id=...>
|
|
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' <S /> 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.")
|
|
|