qwer
This commit is contained in:
10
.gitignore
vendored
Normal file
10
.gitignore
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
# Python-generated files
|
||||||
|
__pycache__/
|
||||||
|
*.py[oc]
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
wheels/
|
||||||
|
*.egg-info
|
||||||
|
|
||||||
|
# Virtual environments
|
||||||
|
.venv
|
||||||
1
.python-version
Normal file
1
.python-version
Normal file
@@ -0,0 +1 @@
|
|||||||
|
3.12
|
||||||
BIN
kptr_table.xlsx
Normal file
BIN
kptr_table.xlsx
Normal file
Binary file not shown.
151
main.py
Normal file
151
main.py
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
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")
|
||||||
7
pyproject.toml
Normal file
7
pyproject.toml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
[project]
|
||||||
|
name = "test12"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Add your description here"
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = []
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user