import xml.etree.ElementTree as ET import csv import sys from bs4 import BeautifulSoup try: tree = ET.parse('/home/x79/sisvietnamvn_01/sisvietnamvn_Trang chính thức hiện tại/bnhvinakhoaquctsiscnth.WordPress.2026-07-28 (5).xml') root = tree.getroot() except Exception as e: print(f"Error parsing XML: {e}") sys.exit(1) ns = { 'wp': 'http://wordpress.org/export/1.2/', 'content': 'http://purl.org/rss/1.0/modules/content/' } attachments = {} for channel in root.findall('channel'): for item in channel.findall('item'): pt = item.find('wp:post_type', ns) if pt is not None and pt.text == 'attachment': post_id = item.find('wp:post_id', ns) url = item.find('wp:attachment_url', ns) if post_id is not None and url is not None: attachments[post_id.text] = url.text csv_mapping = {} with open('/home/x79/sisvietnamvn_01/Media/HÌNH ẢNH BÁC SĨ NGỒI PHÒNG KHÁM/ALL_IMAGES/DANH SÁCH BÁC SĨ NGỒI PHÒNG KHÁM.csv', 'r', encoding='utf-8-sig') as f: reader = csv.DictReader(f) for row in reader: name = row.get('Họ và tên', '').strip() msnv = row.get('MSNV', '').strip() if name: csv_mapping[name.lower()] = msnv def escape_sql(text): if not text: return "NULL" return "'" + text.replace("'", "''") + "'" def parse_html_content(html): if not html: return None, None, None soup = BeautifulSoup(html, 'html.parser') education = "" experience = "" achievements = "" current_section = None # We will just split it simply for now, but a more robust way: # Just save the entire raw HTML into work_experience if we can't easily parse return escape_sql(html), "NULL", "NULL" sql_statements = [] # TRUNCATE TABLE sis_doctor CASCADE? We should probably just insert. # But there might be old data. Let's just generate INSERTs. doctor_id = 1000 for channel in root.findall('channel'): for item in channel.findall('item'): pt = item.find('wp:post_type', ns) if pt is not None and pt.text == 'employee': title_el = item.find('title') raw_title = title_el.text.strip() if title_el is not None and title_el.text else "" # Extract name and title (e.g. "TS.BS TRẦN CHÍ CƯỜNG" -> title="TS.BS", name="TRẦN CHÍ CƯỜNG") parts = raw_title.split(' ', 1) doctor_title = parts[0] if '.' in parts[0] else '' doctor_name = parts[1] if doctor_title and len(parts) > 1 else raw_title if not doctor_title: doctor_name = raw_title doctor_name_lower = doctor_name.lower() msnv = "" for csv_name, code in csv_mapping.items(): if csv_name in doctor_name_lower or doctor_name_lower in csv_name: msnv = code break meta_dict = {} for meta in item.findall('wp:postmeta', ns): k = meta.find('wp:meta_key', ns) v = meta.find('wp:meta_value', ns) if k is not None and k.text and v is not None: meta_dict[k.text] = v.text or "" position = meta_dict.get('position', '') gender = meta_dict.get('gender', '') birthday = meta_dict.get('birthday', '') phone = meta_dict.get('phone_number', '') email = meta_dict.get('email', '') address = meta_dict.get('address', '') order = meta_dict.get('order', '0') image_id = meta_dict.get('image', '') avatar_url = attachments.get(image_id, '') content_el = item.find('content:encoded', ns) html_content = content_el.text if content_el is not None else "" exp, edu, ach = parse_html_content(html_content) if not order.isdigit(): order = '0' # INSERT statement # Use sequenceGenerator.nextval or just let JPA handle it? Since we insert via SQL, we use sequence_generator.nextval sql = f""" INSERT INTO sis_doctor ( id, name, title, avatar_url, doctor_code, active, position, gender, birthday, phone_number, email, address, display_order, work_experience, created_by, created_date, last_modified_by, last_modified_date ) VALUES ( {doctor_id}, {escape_sql(doctor_name)}, {escape_sql(doctor_title)}, {escape_sql(avatar_url)}, {escape_sql(msnv)}, 1, {escape_sql(position)}, {escape_sql(gender)}, {escape_sql(birthday)}, {escape_sql(phone)}, {escape_sql(email)}, {escape_sql(address)}, {order}, {exp}, 'system', sysdate, 'system', sysdate );""" sql_statements.append(sql.strip()) doctor_id += 1 with open('/home/x79/sisvietnamvn_01/sisvietnamvn_main/import_doctors.sql', 'w', encoding='utf-8') as f: f.write("DELETE FROM sis_doctor;\n") f.write("\n".join(sql_statements)) f.write("\nCOMMIT;\n") print("Generated import_doctors.sql")