Files
kadastr12/main.py
2025-06-02 00:21:58 +05:00

151 lines
6.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import xml.etree.ElementTree as ET
import openpyxl
import glob
import os
HEADERS = [
"№ п/п",
"Раздел КПТР",
"Кадастровый номер",
"Кадастровый квартал",
"Вид объекта",
"Площадь ЗУ",
"Погрешность определения площади",
"наличие координат",
"Пояснения"
]
def has_spatial(elem):
"""Проверяет наличие тега SpatialElement в рамках элемента."""
return "да" if elem.find(".//SpatialElement") is not None else "нет"
def get_explanation(elem):
"""Ищет пояснения в тегах Explanation, ExplanationSection, NameSection"""
for tag in ["Explanation", "ExplanationSection", "NameSection"]:
sub = elem.find(f".//{tag}")
if sub is not None and sub.text:
return sub.text.strip()
return ""
def extract_fields(elem, tag):
"""
В зависимости от тега-объекта извлекает данные для строки:
2. Раздел КПТР устанавливается по тегу
3. Кадастровый номер
4. Кадастровый квартал
5. Вид объекта
6. Площадь ЗУ
7. Погрешность определения площади
8. наличие координат
9. Пояснения
"""
if tag in {"NewParcel", "SpecifyParcel"}:
section = "FormParcels" if tag=="NewParcel" else "SpecifyParcels"
cadastral_number = elem.attrib.get("Definition", "")
if cadastral_number.startswith(":"):
cadastral_number = cadastral_number[1:]
cadastral_block = (elem.findtext("CadastralBlock") or "").strip()
# Если внутри есть тег ObjectType берем его, иначе для ЗУ фиксированное значение
ot = elem.findtext("ObjectType")
object_type = ot.strip() if ot else "Земельный участок"
area = (elem.findtext("Area/Area") or "").strip()
inaccuracy = (elem.findtext("Area/Inaccuracy") or "").strip()
coords = has_spatial(elem)
explanation = get_explanation(elem)
return [None, section, cadastral_number, cadastral_block, object_type,
area, inaccuracy, coords, explanation]
elif tag == "CadastralErrorParcel":
# обрабатываем дочерний элемент CadastralErrorExistParcel
sub = elem.find("CadastralErrorExistParcel")
if sub is None:
return None
section = "CadastralErrorsParcels"
cadastral_number = sub.attrib.get("CadastralNumber", "")
cadastral_block = (sub.findtext("CadastralBlock") or "").strip()
area = (sub.findtext("Area/Area") or "").strip()
inaccuracy = (sub.findtext("Area/Inaccuracy") or "").strip()
coords = has_spatial(sub)
explanation = get_explanation(sub)
object_type = "Земельный участок"
return [None, section, cadastral_number, cadastral_block, object_type,
area, inaccuracy, coords, explanation]
elif tag == "ExistParcel":
# элемент имеет атрибут CadastralNumber
section = "ExistParcels"
cadastral_number = elem.attrib.get("CadastralNumber", "")
cadastral_block = (elem.findtext("CadastralBlock") or "").strip()
area = (elem.findtext("Area/Area") or "").strip()
inaccuracy = (elem.findtext("Area/Inaccuracy") or "").strip()
coords = has_spatial(elem)
explanation = get_explanation(elem)
object_type = "Земельный участок"
return [None, section, cadastral_number, cadastral_block, object_type,
area, inaccuracy, coords, explanation]
elif tag == "ExistNewObjectRealty":
section = "ExistNewObjectsRealty"
cadastral_number = (elem.findtext("CadastralNumber") or "").strip()
ot = elem.findtext("ObjectType")
object_type = ot.strip() if ot else "Объект недвижимости"
cb_elem = elem.find("CadastralBlocks/CadastralBlock")
cadastral_block = cb_elem.text.strip() if cb_elem is not None else ""
# Пытаемся взять площадь из <Area/Area> или альтернативный тег
area = (elem.findtext("Area/Area") or elem.findtext("AreaInGKN") or "").strip()
inaccuracy = (elem.findtext("Area/Inaccuracy") or "").strip()
coords = has_spatial(elem)
explanation = get_explanation(elem)
return [None, section, cadastral_number, cadastral_block, object_type,
area, inaccuracy, coords, explanation]
elif tag == "CadastralErrorOKS":
section = "CadastralErrorsOKS"
cadastral_number = elem.attrib.get("CadastralNumber", "")
cb_elem = elem.find("CadastralBlocks/CadastralBlock")
cadastral_block = cb_elem.text.strip() if cb_elem is not None else ""
# Возможно в данном разделе площадь находится в дочернем теге Area
area = (elem.findtext("Area/Area") or "").strip()
inaccuracy = (elem.findtext("Area/Inaccuracy") or "").strip()
coords = has_spatial(elem)
explanation = get_explanation(elem)
object_type = "Объект недвижимости"
return [None, section, cadastral_number, cadastral_block, object_type,
area, inaccuracy, coords, explanation]
else:
return None
def parse_all_stream(xml_file):
"""
Унифицированный итеративный парсинг.
Обрабатываются объекты, у которых тег относится к:
NewParcel, SpecifyParcel, CadastralErrorParcel, ExistParcel,
ExistNewObjectRealty, CadastralErrorOKS.
"""
TARGET_TAGS = {"NewParcel", "SpecifyParcel", "CadastralErrorParcel",
"ExistParcel", "ExistNewObjectRealty", "CadastralErrorOKS"}
context = ET.iterparse(xml_file, events=("end",))
for event, elem in context:
if elem.tag in TARGET_TAGS:
row = extract_fields(elem, elem.tag)
if row:
yield row
elem.clear()
def main(xml_folder, output_excel):
wb = openpyxl.Workbook()
ws = wb.active
ws.append(HEADERS)
row_num = 1
xml_files = glob.glob(os.path.join(xml_folder, "*.xml"))
for xml_file in xml_files:
for row in parse_all_stream(xml_file):
row[0] = row_num # заполняем № п/п
ws.append(row)
row_num += 1
wb.save(output_excel)
print(f"Excel-файл сохранён: {output_excel}")
if __name__ == "__main__":
# Папка с XML-файлами, измените при необходимости.
main("./test", "kptr_table.xlsx")