well-formed XML이란: HTML과 다른 엄격한 파싱 규칙

브라우저 주소창에 태그 하나가 빠진 HTML 문서를 열어도 화면은 대체로 그럭저럭 뜹니다. 그런데 똑같은 실수를 XML 문서에서 저지르면 브라우저는 결과 화면 대신 빨간 글씨의 파싱 오류만 보여줍니다.
이 차이는 XML이 못 만들어진 포맷이라서가 아닙니다. HTML과 XML이 "오류를 만났을 때 무엇을 할지"에 대해 완전히 다른 계약을 파서와 맺고 있기 때문입니다. 그 계약의 이름이 well-formed(정형식)입니다.
요약 ① HTML은 브라우저가 태그 오류를 알아서 복구해 화면을 보여주지만, XML은 파서가 오류를 복구하지 않고 문서 전체를 거부합니다. ② 이 기준을 well-formed라고 부르며, 루트 요소 개수·태그 닫힘·중첩 순서·속성값 따옴표 같은 몇 가지 규칙으로 정해져 있습니다. ③ 이 엄격함은 XML이 시스템 간 데이터 교환 포맷으로 쓰이는 이유이기도 합니다 — 모호하게 해석될 여지 자체를 규칙으로 없애기 때문입니다.
HTML은 왜 웬만한 오류를 봐주는가
HTML5 명세에는 태그가 잘못 닫히거나 순서가 어긋났을 때 브라우저가 정확히 어떻게 복구해야 하는지까지 정해져 있습니다. 여는 태그만 있고 닫는 태그가 없으면, 브라우저는 뒤에 나오는 태그나 문서 끝을 기준으로 그 자리에서 태그가 닫힌 것처럼 처리합니다.
<p> 안에 또 다른 <p>가 나오면 첫 번째 <p>를 자동으로 닫고 새 문단을 시작합니다. 이런 복구 규칙 덕분에 완벽한 문법을 지키지 않은 HTML 문서도 브라우저마다 비슷한 화면으로 뜹니다.
즉 HTML에서 오류는 화면을 멈추는 신호가 아니라, 파서가 알아서 메워야 할 빈칸에 가깝습니다.
XML은 왜 오류 하나로 문서 전체를 거부하는가
XML은 반대의 태도를 취합니다. 문서가 well-formed 조건을 하나라도 어기면, 파서는 복구를 시도하지 않고 처리를 멈추도록 되어 있습니다. 웹 브라우저에 XML 파일을 직접 열었을 때 내용 대신 오류 위치만 알려주는 화면이 뜨는 이유입니다.
well-formed 여부를 가르는 기준은 몇 가지로 정리됩니다.
| 규칙 | 내용 |
|---|---|
| 루트 요소 | 최상위 요소가 정확히 하나여야 합니다 |
| 태그 닫힘 | 모든 여는 태그는 닫는 태그(또는 self-closing />)를 가져야 합니다 |
| 중첩 순서 | 나중에 연 태그가 먼저 닫혀야 합니다(부모보다 자식이 먼저 닫히면 안 됨) |
| 대소문자 | 태그 이름은 대소문자를 구분합니다(<Book>과 </book>은 서로 다른 태그로 취급됩니다) |
| 속성값 | 속성값은 반드시 따옴표로 감싸야 합니다 |
| 특수문자 | 텍스트에 <, &를 그대로 쓰면 안 되고 이스케이프해야 합니다 |
이 중 하나라도 어긋나면 파서는 나머지 내용이 아무리 멀쩡해도 문서 전체를 처리 대상에서 제외합니다. 오류가 한 글자만 있어도 결과는 "일부 성공"이 아니라 "전체 실패"입니다.
왜 이 엄격함이 오히려 장점이 되는가
관대한 파서는 편리하지만 대가가 있습니다. 브라우저마다 오류를 복구하는 방식이 미묘하게 다르면, 같은 코드가 상황에 따라 다르게 해석될 여지가 생깁니다.
XML은 애초에 사람이 읽는 화면이 아니라 서로 다른 시스템끼리 데이터를 주고받는 포맷으로 설계됐습니다. 두 시스템이 같은 문서를 서로 다르게 해석하면 그 자체가 장애입니다. 그래서 XML은 "알아서 짐작해서 보여주는" 관용 대신 "조건을 만족하지 않으면 아예 거부하는" 엄격함을 선택했습니다.
이 덕분에 well-formed 검사를 통과한 XML 문서는 어떤 파서로 열어도 같은 구조로 해석된다는 확신을 가질 수 있습니다. 모호하게 해석될 여지 자체가 규칙으로 미리 차단되어 있기 때문입니다.
문제는 이 규칙을 사람이 눈으로 확인하기가 쉽지 않다는 데 있습니다. 태그 하나가 어디서 안 닫혔는지, 속성값에 따옴표가 빠진 곳이 어디인지 긴 XML 문서에서 줄 단위로 대조하려면 금방 지치는 작업이 됩니다.
XML을 붙여넣으면 들여쓰기 정렬과 압축, well-formed(구조 오류) 검사까지 한 번에 확인할 수 있습니다.

도구가 well-formed 위반을 알려주는 방식
XML 포맷터는 입력창에 XML을 붙여넣는 즉시 브라우저 자체의 XML 파서로 well-formed 여부를 확인합니다. 조건을 모두 만족하면 "well-formed: 구조에 오류가 없습니다"라는 문구가 뜨고, 하나라도 어긋나면 "well-formed 아님"과 함께 파서가 판단한 구체적인 오류 내용이 그대로 나타납니다.
이 판정과는 별개로, 정렬(들여쓰기)·압축(한 줄) 결과 자체는 태그를 최대한 인식해서 보여주려고 시도합니다. 오류 메시지로 어디가 문제인지 확인하면서, 동시에 지금 입력한 내용이 어떤 구조로 읽히는지도 함께 볼 수 있습니다.
결과 화면에는 입력 크기·출력 크기·요소(태그) 수도 함께 표시되어, 정렬 전후로 용량이 얼마나 달라졌는지도 바로 확인할 수 있습니다.
입력 방법과 옵션
XML 입력 칸에는 직접 붙여넣어도 되고, .xml·.svg·.rss·.xsl 확장자의 파일을 끌어다 놓거나 클릭해서 불러올 수도 있습니다. 정렬 모드에서는 들여쓰기 단위를 공백 2칸·4칸·탭 중에서 고를 수 있고, 압축 모드는 공백을 모두 제거해 한 줄로 만들어줍니다.
결과는 복사 버튼으로 바로 가져갈 수 있고, 새로 확인하려면 지우기 버튼으로 입력을 비우면 됩니다.
정리
- HTML은 브라우저가 태그 오류를 알아서 복구해 화면을 보여주지만, XML은 파서가 오류를 복구하지 않고 문서 전체를 거부합니다.
- 이 기준을 well-formed라고 부르며, 루트 요소 개수·태그 닫힘·중첩 순서·대소문자·속성값 따옴표·특수문자 이스케이프 같은 규칙으로 정해져 있습니다.
- 오류가 한 곳만 있어도 결과는 "일부 성공"이 아니라 "문서 전체 실패"입니다.
- 이 엄격함은 서로 다른 시스템이 같은 문서를 똑같이 해석하도록 보장하기 위한 설계이며, 모호하게 해석될 여지를 없애는 장점이 됩니다.
- XML 포맷터에 붙여넣으면 well-formed 여부와 구체적인 오류 내용을 즉시 확인할 수 있고, 정렬·압축 결과도 함께 볼 수 있습니다.
XML을 붙여넣으면 들여쓰기 정렬과 압축, well-formed(구조 오류) 검사까지 한 번에 확인할 수 있습니다.
자주 묻는 질문
HTML에는 well-formed 같은 규칙이 아예 없나요?
일반 HTML5 문서에는 별도의 well-formed 요구가 없고, 대신 오류를 만났을 때 브라우저가 어떻게 복구할지를 정한 파싱 규칙이 적용됩니다. 다만 XHTML처럼 HTML을 XML 규칙으로 작성하는 방식도 있는데, 이 경우에는 XML과 똑같이 well-formed 조건을 만족해야 하고 어기면 화면이 뜨지 않습니다.
XML 오류 메시지가 떴는데 어디가 문제인지 못 찾겠어요.
대부분 안 닫힌 태그, 속성값에 따옴표가 빠진 경우, 최상위 요소가 두 개 이상인 경우, 텍스트에 <나 &를 그대로 쓴 경우 중 하나입니다. XML 포맷터에 그대로 붙여넣으면 브라우저 파서가 판정한 구체적인 오류 내용이 화면에 표시되므로, 그 문구를 단서로 해당 위치를 찾아가면 됩니다.
XML도 HTML처럼 관대하게 만들면 안 되나요?
그렇게 하지 않는 데는 이유가 있습니다. 관대한 파서는 브라우저마다 복구 방식이 조금씩 달라질 수 있어, 같은 문서가 상황에 따라 다르게 해석될 여지를 남깁니다. XML은 사람이 보는 화면이 아니라 서로 다른 시스템이 데이터를 주고받는 포맷이라 그런 해석 차이 자체가 없어야 하므로, 관용 대신 엄격함을 선택한 것입니다.
압축(한 줄)한 결과도 well-formed 검사를 다시 받아야 하나요?
정렬이든 압축이든 원본 XML의 태그 구조 자체는 바뀌지 않으므로, 원본이 well-formed였다면 압축한 결과도 well-formed입니다. XML 포맷터의 well-formed 판정은 입력한 원본 내용을 기준으로 이루어지며, 정렬·압축 모드 전환과는 별개로 동작합니다.
