Watch at Ease세상을 읽고, 일상의 답을 찾다.

기술 · 실용 가이드

minidom에서 빈 줄이 늘어나나요? 지우기 전에 본문 보존을 검증하세요

XML이 깔끔해져도 텍스트는 달라질 수 있습니다. 저장 반복과 Python 버전을 확인하고 의미를 비교한 뒤 원본을 교체하세요.

XML 공백이 본문을 바꾸는 자체 제작 도식
자체 제작 일러스트: 파싱 성공에도 줄바꿈 추가와 의도한 빈 줄 삭제가 숨을 수 있습니다. Watch at Ease

커지는 XML을 고치려고 모든 빈 줄을 지우지 마세요. 어떤 공백을 버려도 되는지, 설치된 직렬화기가 본문을 바꾸는지 먼저 입증하세요. 파싱이 돼도 의미가 이미 사라졌을 수 있습니다.

1. 저장 주기와 런타임을 고정하세요

원본과 버릴 수 있는 복사본을 보관하세요. sys.version, 파서, 직렬화 호출, indent/newl 인수와 입력의 기존 들여쓰기 여부를 기록합니다. 편집하지 않고 같은 파싱·편집·저장 주기를 반복해도 출력이 커진다면 새 요소보다 서식을 조사하세요.

CPython 3.12.14에서 들여쓴root와item 하나를 시험했습니다. 첫toprettyxml(indent=' ') 후 공백 줄4개, 다시 파싱해 출력하면8개였습니다. 이 수치는 작은 합성 사례의 결과이며 모든 XML의 규칙이 아닙니다.

2. 공백도 본문일 수 있습니다

<p>Hello <b>world</b>!</p>에서는 하위 텍스트Hello world!에 줄바꿈과 들여쓰기가 더해졌습니다. 별도<p><b>A</b> <b>B</b></p>에서도 한 칸 공백 구분자가 바뀌었습니다. 태그 개수나 파싱 성공만 확인하면 둘 다 놓칩니다.

의도한 빈 줄과xml:space='preserve'가 있는 사례도3.12.14에서는 재서식화됐습니다. if line.strip()로 예쁜 출력을 걸러내자 그 빈 줄도 삭제됐습니다. W3C의preserve는 재정의되지 않으면 하위 요소에 상속되는 보존 의도입니다. 설치된 모든 포매터가 구현했다는 증거는 아닙니다.

3. 전체 필터보다 범위가 명확한 수정을 선택하세요

시험한 버전에서 공백 의미를 모르면 편집한DOM을toxml(encoding='utf-8')로 직렬화하고 바이트를 새 파일에 쓰세요. 새로운 들여쓰기를 피하지만 기존 공백을 지우거나 이전 저장에서 바뀐 내용을 복구하지는 않습니다.4개 사례 모두 파싱된 하위 텍스트가 보존됐고 두 번째 파싱·toxml 결과도 같았습니다.

보기용 서식 사본과 저장 문서를 분리하세요. 문서 콘텐츠 모델이나 앱 계약이 무시 가능하다고 정한 곳에서만 배치 노드를 제거합니다. lxml FAQ는 확정적 지식이 없으면remove_blank_text가 휴리스틱을 쓴다고 명시합니다. 라이브러리를 바꾸는 것만으로 보존이 입증되지는 않습니다.

4. 외관이 아닌 의미로 승인하세요

Python 3.16 개발 문서는 혼합 콘텐츠와xml:space='preserve' 처리 변경을 기록합니다. 이를3.12 동작으로 가정하거나 업그레이드가 이미 바뀐 본문을 복구한다고 생각하지 마세요. 실제 실행한 버전은3.12.14뿐입니다. 교체할 정확한 버전에서 대표 사례를 다시 시험하세요.

원본 교체 전에 후보를 다시 파싱하고 요소 순서·속성·모든 텍스트 구간을 비교하세요. 보호되거나 혼합된 콘텐츠의 공백 전용 구간도 포함하며 명시적으로 승인한 배치 예외만 허용합니다. 두 번째 저장과 소비 앱도 시험하고 백업을 보관하세요. toxml은 원본 바이트 보존·정규화·서명·엔티티 표기나 모든 문서 기능을 보장하지 않습니다. 신뢰 가능한 합성 사례이며 신뢰할 수 없는 XML의 보안 처리 지침이 아닙니다.

XML 두 번 저장 검증 도식
자체 제작 일러스트: 실행 버전·전체 텍스트 구간·두 번째 저장을 확인합니다. Watch at Ease