위에서 파일을 고르면 바로 열립니다.준비됨 — 인터넷을 끊어도 이대로 동작합니다.이 브라우저에서는 쓸 수 없습니다 (나머지는 그대로 동작합니다).오프라인 저장에는 https:// 또는 localhost가 필요합니다.여기서는 저장할 수 없지만, 어느 쪽이든 올라가는 것은 없습니다.파일은 어디로도 가지 않았습니다. 파일 {total}개를 불러왔고 모두 이 사이트의 것입니다. {platform}무언가가 {hosts}에 접속했는데, 이 도구는 절대 그러지 않습니다. 살펴볼 만합니다. {platform}광고와 측정과 후원 버튼을 위한 이 사이트 자신의 스크립트가 호스트 {hosts}곳에서 왔습니다. 그중 어느 쪽도 파일이나 그 1바이트도 받지 않았습니다.광고와 측정과 후원 버튼을 위한 이 사이트 자신의 스크립트가 호스트 {hosts}곳에서 왔습니다. 그중 어느 쪽도 파일이나 그 1바이트도 받지 않았습니다.문제가 생겼습니다: {detail}. 처음부터 다시 하려면 페이지를 새로 고치세요.파일 {count}개를 읽는 중…파일 {count}개를 읽는 중…예시로 해 보기예시를 만드는 중…이 브라우저에서는 예시를 만들지 못했습니다. 대신 파일을 골라 주세요.
XML 포맷터 — 펼치거나, 납작하게 누르거나, JSON으로
읽으라고 펼친 XML, 보내라고 납작하게 누른 XML, 그리고 양쪽으로 오가는 JSON 변환. 그 어느 것도 남의 서버에 붙여 넣지 않습니다.
포맷과 변환은 문자열에 대한 산술이고, 그 일이 여기, 이 페이지에서 벌어집니다. 파서는 손으로 쓴 것이고 src/shared/parse-xml.js에 있으며, 그 밖에는 아무것도 없습니다. 이 도구에는 네트워크 기능 자체가 없어서 가져올 것도 보낼 것도 없습니다. 그것이 여기서는 ‘XML’이라는 말이 풍기는 것보다 더 무겁게 다가옵니다. 이 형식으로 들어오는 것은 대개 청구서나 은행 거래 내역서, 진료 기록, 아니면 헤더에 누군가의 자격 증명이 들어 있는 SOAP 요청이기 때문입니다.
✗ 업로드 없음
✗ 가입 없음
✗ 용량 제한 없음
✓ 오프라인 동작
✓ 오픈 소스
실시간 확인:확인 중…
오프라인:확인 중…
말을 믿으실 필요는 없습니다. 개발자 도구를 열고 네트워크 탭을 보면서 무언가를 포맷해 보세요. 어느 요청에도 붙여 넣으신 내용의 한 글자조차 실리지 않습니다. 아니면 인터넷을 끊고 그대로 포맷해 보셔도 됩니다.
이 약속을 직접 확인하는 방법
붙여 넣은 것이 나갈 곳이 없습니다. Content-Security-Policy에는 이 페이지가 연결할 수 있는 모든 주소가 적혀 있고, 그중 우리 것은 하나도 없습니다. 붙여 넣은 청구서가 수집될 만한 엔드포인트가 여기에는 없고, 설령 있다 해도 그리로 보낼 코드가 없습니다.
여기서는 아무것도 가져오지 않습니다.src/ 어디에도 fetch도, XMLHttpRequest도, sendBeacon도 없습니다. 파서와 프린터는 문자열을 받아 문자열을 돌려주는, 이 페이지 안의 함수입니다.
외부 엔티티는 결코 해석되지 않습니다. 외부 엔티티가 들어 있는 DOCTYPE은 XML 파서를 구슬려 파싱 중인 그 기기의 파일을 읽게 만드는 방법이고, 이 형식의 가장 오래된 구멍입니다. src/shared/parse-xml.js는 엔티티 해석이 아예 들어 있지 않은, 손으로 쓴 리더입니다. 꺼 둔 것이 아니라 없는 것이고, 이 페이지는 사용자의 텍스트를 브라우저 자신의 DOMParser에 넘기지도 않습니다.
XML에서 나오는 모든 값은 문자열입니다.<port>8080</port>은 그것이 숫자인지에 대해 아무 말도 하지 않으므로, JSON은 "8080"이라고 씁니다. 대신 정해 주는 것은, 마치 파일에 있었던 것처럼 계속 실려 다니게 될 정보를 지어내는 일입니다.
구글이 불러오는 것과, 구글에 주지 않는 것. 광고와 측정 스크립트는 구글에서, 후원 버튼은 Buy Me a Coffee에서 옵니다. 그 어느 쪽에도 사용자의 텍스트는 한 글자도 건네지지 않습니다. 그것을 읽고 파싱하고 쓰는 모든 줄은 이 오리진에서 제공되며 저장소에 올라 있습니다.
오프라인에서 동작합니다. 네트워크를 끊어도 이 도구는 그대로입니다. 애초에 네트워크 단계가 없었기 때문입니다. 가장 간단한 증명입니다.
직접 확인해 보세요. 위에 적은 어느 것도 그냥 믿으실 필요는 없습니다. 이 페이지는 저장소 안의 템플릿과 설정을 빌드 스크립트가 찍어 낸 결과이고, 그 스크립트는 누구나 읽고 직접 돌려 볼 수 있습니다. 결과물은 dist 브랜치에 그대로 올라가 있고요. 그래서 실제로 제공되는 파일과 소스를 빌드한 결과를 나란히 놓고 비교해 보실 수 있습니다:
먼저 읽어 볼 파일을 꼽자면, Content-Security-Policy는 config/site.toml, 어떤 태그가 끝내 닫히지 않았는지 알려 주는 파서는 src/shared/parse-xml.js를, XML에서 나오는 모든 값이 왜 짐작되지 않고 문자열로 남는지는 src/convert.js를 보세요.
회사 보안 소프트웨어가 업로드를 경고한다면. 그것은 브라우저에서 파일이 선택되는 순간을 지켜보며, 페이지가 그것을 보낼 생각인지는 알 수 없습니다 — 그래서 고르는 순간에 경고합니다. 여기서는 아무것도 보내지 않습니다. 브라우저 개발자 도구를 열고 네트워크 탭으로 옮긴 뒤 파일을 골라 보세요. 그것을 실어 나르는 요청은 없고, 이 페이지 자체의 로컬 미리보기 말고는 요청 자체가 없습니다. 같은 확인을 IT 팀도 삼십 초면 할 수 있습니다.
1 할 일 고르기
배치 납작하게 압축한 것은 읽기 좋으라고만 있던 공백을 모두 뺀 같은 문서입니다.
바깥 요소의 이름 XML에는 맨 위에 요소가 하나 있어야 하는데 JSON에는 없으므로, 하나를 지어내야 합니다.
{reason} ({line}행 {column}열)텍스트의 끝줄바꿈탭«{ch}»이 주석이 끝내 닫히지 않습니다이 CDATA 구역이 끝내 닫히지 않습니다이 선언이 끝내 닫히지 않습니다이 닫는 태그가 끝내 완성되지 않습니다<{name}>이(가) 끝내 닫히지 않습니다</{name}>이(가) 열린 적 없는 태그를 닫습니다<{open}>이(가) 아직 열려 있는데 </{name}>이(가) 요소를 닫습니다<{name}> 안에 예상하지 못한 «{ch}»이(가) 있습니다태그 이름은 글자로 시작해야 합니다<{name}>이(가) 끝내 완성되지 않습니다«{name}» 속성에 값이 없는데, XML은 이를 허용하지 않습니다이 속성 값이 끝내 닫히지 않습니다XML에서 속성 값은 따옴표로 감싸야 합니다값이 끝난 뒤에 {found}이(가) 있습니다텍스트가 너무 일찍 끝났습니다키는 큰따옴표로 감싼 문자열이어야 하는데, 이것은 {found}입니다키 다음에 콜론이 와야 하는데 {found}이(가) 있습니다{found}은(는) 예상하지 못한 것입니다쉼표나 닫는 중괄호가 와야 하는데 {found}이(가) 있습니다쉼표나 닫는 대괄호가 와야 하는데 {found}이(가) 있습니다이 객체가 끝내 닫히지 않습니다이 배열이 끝내 닫히지 않습니다이 문자열이 끝내 닫히지 않습니다\u 뒤에는 16진수 네 자리가 와야 합니다\{next}은(는) JSON이 아는 이스케이프가 아닙니다문자열 안에 날것의 제어 문자가 있습니다 — 이스케이프로 쓰세요이것은 JSON이 허용하는 숫자가 아닙니다XML에서 JSON으로JSON에서 XML로속성은 이름에 @가 붙은 멤버가 되고, 요소 자신의 텍스트는 자리를 나눠야 할 때 #text가 되며, 모든 값은 문자열로 남습니다 — XML은 어느 것이 숫자인지 한 번도 말한 적이 없습니다.배열은 되풀이되는 요소가 됩니다. 되읽을 수 있는 모양은 그것뿐입니다. 빈 객체와 빈 문자열은 둘 다 빈 요소로 나옵니다.{n} B{n} KB{n} MB파일을 읽는 중…그 파일은 읽지 못했습니다: {reason}아직 아무것도 없습니다.아무것도 나오지 않았습니다.XML, 납작하게 압축XML, 보기 좋게 정리{what} — {before}에서 {after}로, {percent}% 감소{what} — {lines}줄, {size}{name} — {lines}줄, {size}복사복사했습니다선택했습니다 — Ctrl+C를 누르세요XML은 어디로도 가지 않았습니다. 파일 {total}개를 불러왔습니다. {platform}무언가가 {hosts}에 접속했는데, 이 도구는 절대 그러지 않습니다. {platform}광고와 측정과 후원 버튼을 위한 이 사이트 자신의 스크립트가 호스트 {hosts}곳에서 왔습니다. 그중 어느 쪽도 그 한 글자도 받지 않았습니다.광고와 측정과 후원 버튼을 위한 이 사이트 자신의 스크립트가 호스트 {hosts}곳에서 왔습니다. 그중 어느 쪽도 그 한 글자도 받지 않았습니다.
원하는 결과가 나왔나요?
무엇이 잘못됐나요?
고맙습니다 — 큰 도움이 됩니다.
보내지는 것은 답변뿐이고, 그것도 버튼을 눌렀을 때만입니다. 파일도, 파일 이름도, 파일에 관한 어떤 정보도 보내지 않습니다.
# XML 포맷터 — 펼치거나, 납작하게 누르거나, JSON으로
읽으라고 펼친 XML, 보내라고 납작하게 누른 XML, 그리고 양쪽으로 오가는 JSON 변환. 그 어느 것도 남의 서버에 붙여 넣지 않습니다.
> XML을 포맷하고 들여쓰고 압축하며, XML을 JSON으로 또는 JSON을 XML로 바꿉니다. 파서가 브라우저에서 돌고 아무것도 업로드되지 않아서, 피드도 청구서도 설정 파일도 기기를 떠나지 않습니다.
이 페이지는 브라우저 안에서만 동작하는 대화형 도구입니다(https://abox.tools/ko/xml-포맷터/). 도구에 넘긴 어떤 것도 업로드되지 않습니다. 아래는 이 페이지가 도구에 대해 글로 설명하는 내용 전부입니다. 도구를 쓰려면 이 주소를 여세요.
## XML과 JSON은 **절대 업로드되지 않습니다**. 서버가 아예 없으니까요.
포맷과 변환은 문자열에 대한 산술이고, 그 일이 여기, 이 페이지에서 벌어집니다. 파서는 손으로 쓴 것이고 `src/shared/parse-xml.js`에 있으며, 그 밖에는 아무것도 없습니다. 이 도구에는 네트워크 기능 자체가 없어서 가져올 것도 보낼 것도 없습니다. 그것이 여기서는 ‘XML’이라는 말이 풍기는 것보다 더 무겁게 다가옵니다. 이 형식으로 들어오는 것은 대개 청구서나 은행 거래 내역서, 진료 기록, 아니면 헤더에 누군가의 자격 증명이 들어 있는 SOAP 요청이기 때문입니다.
- ✗ 업로드 없음
- ✗ 가입 없음
- ✗ 용량 제한 없음
- ✓ 오프라인 동작
- ✓ 오픈 소스
## XML을 업로드하지 않고 포맷하는 방법
1. **할 일을 고르세요.** 탭 둘에 입력란 하나입니다. *포맷*은 XML을 펼치거나 납작하게 누르고, *변환*은 그것을 JSON으로, 또는 JSON을 다시 XML로 돌립니다. 방금 펼친 XML이 그대로 변환할 XML이라, 두 번 붙여 넣을 일이 없습니다.
2. **붙여 넣거나, 파일을 놓으세요.** 선택해서 복사할 수 있는 것이면 무엇이든 됩니다. `.xml`, `.svg`, `.rss`, `.xsd` 파일을 선택기에 놓으면 사용자의 브라우저가 읽어서 입력란에 넣습니다. 건너뛸 업로드 단계 자체가 없습니다.
3. **들여쓰기를 고르거나, 납작하게 누르세요.** 공백 두 칸, 네 칸, 또는 탭. 납작하게 누른 것은 읽기 좋으라고만 있던 공백을 모두 뺀 같은 문서이고, 결과가 그것으로 몇 바이트를 아꼈는지 알려 줍니다.
4. **오류가 있는 자리에서 오류를 읽으세요.** 여기서 실패한 파서는, 브라우저가 한 번에 읽어 낸 문서를 두고 하는 ‘1행 오류’ 대신 *어떤 태그가* 끝내 닫히지 않았는지를 몇 행 몇 열인지와 함께 말해 줍니다.
5. **결과를 가져가세요.** 복사하거나, 나온 형식의 이름이 붙은 파일로 내려받으세요.
## 상자 속 다른 도구
- [텍스트 비교](https://abox.tools/ko/텍스트-비교/): 두 텍스트를 넣으면 모든 차이가 줄 단위, 단어 단위로 표시됩니다. 남의 서버에 붙여 넣는 것은 없습니다.
- [Base64 인코더 · 디코더](https://abox.tools/ko/base64-인코딩/): Base64, 퍼센트 인코딩, HTML 엔티티, 16진수, 역슬래시 이스케이프를 양방향으로. 남의 서버에 붙여 넣는 것은 없습니다.
- [텍스트·파일 공유](https://abox.tools/ko/텍스트-공유/): 공유는 이 열린 탭 안에서만 삽니다. 읽는 사람은 암호화된 내용을 당신의 브라우저에서 직접 받아 가고, 탭을 닫으면 끝납니다 - 어떤 서버에도 아무것도 남지 않습니다.
- [QR과 바코드 생성](https://abox.tools/ko/qr코드-만들기/): 입력하면 코드가 됩니다. 만드는 데 아무것도 나가지 않습니다.
## 자주 묻는 질문
### 제 XML이 어딘가로 업로드되나요?
아닙니다. 이 페이지의 파서와 프린터는 사용자의 브라우저에서, 사용자의 하드웨어 위에서 도는 함수입니다. 이 도구에는 네트워크 기능 자체가 없어서 무언가를 가져오지도, 보내지도 않습니다. 페이지의 `Content-Security-Policy`에는 연결할 수 있는 모든 주소가 적혀 있고 그중 우리 것은 하나도 없습니다. 이것은 XML에서 이 형식의 평판이 풍기는 것보다 더 무거운 이야기입니다. 여기 들어오는 것은 대개 청구서나 은행 거래 내역서, 진료 기록, 아니면 헤더에 자격 증명이 들어 있는 SOAP 요청이기 때문입니다.
### 외부 엔티티를 해석하나요?
아닙니다. 끌 것도 없습니다. 외부 엔티티 해석은 XML 파서를 구슬려 그것을 실행하는 기기의 파일을 읽게 만드는 방법이고, 보통 XXE라고 쓰는 공격입니다. `src/shared/parse-xml.js`는 엔티티 해석이 전혀 없는, 손으로 쓴 리더입니다. 사용자의 텍스트가 브라우저 자신의 `DOMParser`로 넘어가는 일도 없습니다. `DOCTYPE`은 한 번도 실행되지 않은 채 그대로 지나갑니다.
### XML을 JSON으로 바꾸면 무엇을 잃나요?
혼합 내용의 순서, 주석, 그리고 속성과 자식 요소의 차이입니다. 마지막 것은 지워지기보다 누그러집니다. 속성은 이름이 `@`로 시작하는 멤버가 되기 때문입니다. 요소 자신의 텍스트는 다른 것과 나란히 있어야 할 때 `#text`가 되고, 반복되는 자식은 배열이 됩니다. 모든 값은 문자열로 남습니다. XML에는 타입이 없고, `8080`이 숫자였다고 정하는 것은 정보를 지어내는 일이 됩니다.
### JSON을 XML로 바꾸면 무엇을 잃나요?
빈 객체와 빈 배열과 빈 문자열의 차이입니다. 셋 다 빈 요소가 됩니다. 그리고 모든 값의 타입도 잃습니다. XML에는 타입이 없기 때문입니다. 배열은 반복되는 요소가 되는데, 그것이 다시 읽히는 유일한 모양입니다. 요소 이름이 감당하지 못하는 키는, 어떤 파서도 읽지 않을 문서를 내놓는 대신 껄끄러운 문자를 바꿔 넣습니다.
### SVG나 RSS 피드, POM 파일도 포맷할 수 있나요?
됩니다. 셋 다 XML이고, 이것은 특정 방언이 아니라 XML을 읽습니다. 이렇게 펼친 SVG는 손으로 고치기 쉬워집니다. RSS나 Atom 피드는 보통 납작하게 눌린 채로 배포되어 무언가가 펼치기 전까지는 읽을 수 없습니다. 어떻게 늘어놓든 문서의 뜻은 달라지지 않습니다.
### 다시 들여쓰면 XML의 뜻이 달라지나요?
요소가 요소를 담고 있는 문서라면 달라지지 않습니다. 문제가 될 수 있는 것은 텍스트입니다. 낱말을 담은 요소 안의 공백은 그 텍스트의 일부이므로, 텍스트만 담은 요소는 펼치지 않고 한 줄에 그대로 둡니다. `CDATA` 구간은 있던 그대로 옮겨집니다.
### 왜 브라우저 자신의 XML 파서를 쓰지 않나요?
문서가 깨졌을 때 하는 말 때문입니다. `DOMParser`는 오류 문서를 돌려주는데, 그 표현은 브라우저마다 다르고 흔히 ‘1행 오류’로 귀결됩니다. 손으로 쓴 리더는 어떤 태그가 끝내 닫히지 않았는지, 그것이 어디서 열렸는지를 말해 줄 수 있고, 그것이 바로 알고 싶었던 바입니다. 외부 엔티티를 해석하지 않는다는 것이 나머지 이유입니다.
### 얼마나 큰 파일까지 다룰 수 있나요?
여기에 걸어 둔 제한은 없습니다. 그 값을 치를 서버가 없기 때문입니다. 실제 한계는 사용자의 기기입니다. 몇 메가바이트짜리 XML은 괜찮고, 아주 긴 문서에서는 키보드를 두고 다투는 대신 입력이 멎기를 기다렸다가 다시 포맷합니다.
### 무료인가요? 가입해야 하나요?
무료이고 계정도, 로그인도, 체험 기간도 없으며 얼마나 붙여 넣든 제한이 없습니다. 이 사이트에는 광고가 있고 그것이 비용을 댑니다. 광고에는 텍스트에 관한 것이 아무것도 주어지지 않습니다.
### 오프라인에서도 되나요?
됩니다. 페이지를 한 번 불러온 뒤 인터넷을 끊어도 계속 동작합니다. 이것이 아무것도 업로드되지 않는다는 가장 간단한 증명이기도 합니다. XML을 포맷하러 밖으로 보내는 도구라면 선을 뽑는 순간 멈췄을 것입니다.
## 이 약속을 직접 확인하는 방법
- **붙여 넣은 것이 나갈 곳이 없습니다.** Content-Security-Policy에는 이 페이지가 연결할 수 있는 모든 주소가 적혀 있고, 그중 우리 것은 하나도 없습니다. 붙여 넣은 청구서가 수집될 만한 엔드포인트가 여기에는 없고, 설령 있다 해도 그리로 보낼 코드가 없습니다.
- **여기서는 아무것도 가져오지 않습니다.** `src/` 어디에도 `fetch`도, `XMLHttpRequest`도, `sendBeacon`도 없습니다. 파서와 프린터는 문자열을 받아 문자열을 돌려주는, 이 페이지 안의 함수입니다.
- **외부 엔티티는 결코 해석되지 않습니다.** 외부 엔티티가 들어 있는 `DOCTYPE`은 XML 파서를 구슬려 파싱 중인 그 기기의 파일을 읽게 만드는 방법이고, 이 형식의 가장 오래된 구멍입니다. `src/shared/parse-xml.js`는 엔티티 해석이 아예 들어 있지 않은, 손으로 쓴 리더입니다. 꺼 둔 것이 아니라 없는 것이고, 이 페이지는 사용자의 텍스트를 브라우저 자신의 `DOMParser`에 넘기지도 않습니다.
- **XML에서 나오는 모든 값은 문자열입니다.** `<port>8080</port>`은 그것이 숫자인지에 대해 아무 말도 하지 않으므로, JSON은 `"8080"`이라고 씁니다. 대신 정해 주는 것은, 마치 파일에 있었던 것처럼 계속 실려 다니게 될 정보를 지어내는 일입니다.
- **구글이 불러오는 것과, 구글에 주지 않는 것.** 광고와 측정 스크립트는 구글에서, 후원 버튼은 Buy Me a Coffee에서 옵니다. 그 어느 쪽에도 사용자의 텍스트는 한 글자도 건네지지 않습니다. 그것을 읽고 파싱하고 쓰는 모든 줄은 이 오리진에서 제공되며 저장소에 올라 있습니다.
- **오프라인에서 동작합니다.** 네트워크를 끊어도 이 도구는 그대로입니다. 애초에 네트워크 단계가 없었기 때문입니다. 가장 간단한 증명입니다.
**직접 확인해 보세요.** 위에 적은 어느 것도 그냥 믿으실 필요는 없습니다. 이 페이지는 저장소 안의 템플릿과 설정을 빌드 스크립트가 찍어 낸 결과이고, 그 스크립트는 누구나 읽고 직접 돌려 볼 수 있습니다. 결과물은 `dist` 브랜치에 그대로 올라가 있고요. 그래서 실제로 제공되는 파일과 소스를 빌드한 결과를 나란히 놓고 비교해 보실 수 있습니다: https://github.com/A-Box-of-Tools/website
먼저 읽어 볼 파일을 꼽자면, Content-Security-Policy는 `config/site.toml`, 어떤 태그가 끝내 닫히지 않았는지 알려 주는 파서는 `src/shared/parse-xml.js`를, XML에서 나오는 모든 값이 왜 짐작되지 않고 문자열로 남는지는 `src/convert.js`를 보세요.
XML을 업로드하지 않고 포맷하는 방법
할 일을 고르세요. 탭 둘에 입력란 하나입니다. 포맷은 XML을 펼치거나 납작하게 누르고, 변환은 그것을 JSON으로, 또는 JSON을 다시 XML로 돌립니다. 방금 펼친 XML이 그대로 변환할 XML이라, 두 번 붙여 넣을 일이 없습니다.
붙여 넣거나, 파일을 놓으세요. 선택해서 복사할 수 있는 것이면 무엇이든 됩니다. .xml, .svg, .rss, .xsd 파일을 선택기에 놓으면 사용자의 브라우저가 읽어서 입력란에 넣습니다. 건너뛸 업로드 단계 자체가 없습니다.
들여쓰기를 고르거나, 납작하게 누르세요. 공백 두 칸, 네 칸, 또는 탭. 납작하게 누른 것은 읽기 좋으라고만 있던 공백을 모두 뺀 같은 문서이고, 결과가 그것으로 몇 바이트를 아꼈는지 알려 줍니다.
오류가 있는 자리에서 오류를 읽으세요. 여기서 실패한 파서는, 브라우저가 한 번에 읽어 낸 문서를 두고 하는 ‘1행 오류’ 대신 어떤 태그가 끝내 닫히지 않았는지를 몇 행 몇 열인지와 함께 말해 줍니다.
아닙니다. 이 페이지의 파서와 프린터는 사용자의 브라우저에서, 사용자의 하드웨어 위에서 도는 함수입니다. 이 도구에는 네트워크 기능 자체가 없어서 무언가를 가져오지도, 보내지도 않습니다. 페이지의 Content-Security-Policy에는 연결할 수 있는 모든 주소가 적혀 있고 그중 우리 것은 하나도 없습니다. 이것은 XML에서 이 형식의 평판이 풍기는 것보다 더 무거운 이야기입니다. 여기 들어오는 것은 대개 청구서나 은행 거래 내역서, 진료 기록, 아니면 헤더에 자격 증명이 들어 있는 SOAP 요청이기 때문입니다.
외부 엔티티를 해석하나요?
아닙니다. 끌 것도 없습니다. 외부 엔티티 해석은 XML 파서를 구슬려 그것을 실행하는 기기의 파일을 읽게 만드는 방법이고, 보통 XXE라고 쓰는 공격입니다. src/shared/parse-xml.js는 엔티티 해석이 전혀 없는, 손으로 쓴 리더입니다. 사용자의 텍스트가 브라우저 자신의 DOMParser로 넘어가는 일도 없습니다. DOCTYPE은 한 번도 실행되지 않은 채 그대로 지나갑니다.
XML을 JSON으로 바꾸면 무엇을 잃나요?
혼합 내용의 순서, 주석, 그리고 속성과 자식 요소의 차이입니다. 마지막 것은 지워지기보다 누그러집니다. 속성은 이름이 @로 시작하는 멤버가 되기 때문입니다. 요소 자신의 텍스트는 다른 것과 나란히 있어야 할 때 #text가 되고, 반복되는 자식은 배열이 됩니다. 모든 값은 문자열로 남습니다. XML에는 타입이 없고, 8080이 숫자였다고 정하는 것은 정보를 지어내는 일이 됩니다.
JSON을 XML로 바꾸면 무엇을 잃나요?
빈 객체와 빈 배열과 빈 문자열의 차이입니다. 셋 다 빈 요소가 됩니다. 그리고 모든 값의 타입도 잃습니다. XML에는 타입이 없기 때문입니다. 배열은 반복되는 요소가 되는데, 그것이 다시 읽히는 유일한 모양입니다. 요소 이름이 감당하지 못하는 키는, 어떤 파서도 읽지 않을 문서를 내놓는 대신 껄끄러운 문자를 바꿔 넣습니다.
SVG나 RSS 피드, POM 파일도 포맷할 수 있나요?
됩니다. 셋 다 XML이고, 이것은 특정 방언이 아니라 XML을 읽습니다. 이렇게 펼친 SVG는 손으로 고치기 쉬워집니다. RSS나 Atom 피드는 보통 납작하게 눌린 채로 배포되어 무언가가 펼치기 전까지는 읽을 수 없습니다. 어떻게 늘어놓든 문서의 뜻은 달라지지 않습니다.
다시 들여쓰면 XML의 뜻이 달라지나요?
요소가 요소를 담고 있는 문서라면 달라지지 않습니다. 문제가 될 수 있는 것은 텍스트입니다. 낱말을 담은 요소 안의 공백은 그 텍스트의 일부이므로, 텍스트만 담은 요소는 펼치지 않고 한 줄에 그대로 둡니다. CDATA 구간은 있던 그대로 옮겨집니다.
왜 브라우저 자신의 XML 파서를 쓰지 않나요?
문서가 깨졌을 때 하는 말 때문입니다. DOMParser는 오류 문서를 돌려주는데, 그 표현은 브라우저마다 다르고 흔히 ‘1행 오류’로 귀결됩니다. 손으로 쓴 리더는 어떤 태그가 끝내 닫히지 않았는지, 그것이 어디서 열렸는지를 말해 줄 수 있고, 그것이 바로 알고 싶었던 바입니다. 외부 엔티티를 해석하지 않는다는 것이 나머지 이유입니다.
얼마나 큰 파일까지 다룰 수 있나요?
여기에 걸어 둔 제한은 없습니다. 그 값을 치를 서버가 없기 때문입니다. 실제 한계는 사용자의 기기입니다. 몇 메가바이트짜리 XML은 괜찮고, 아주 긴 문서에서는 키보드를 두고 다투는 대신 입력이 멎기를 기다렸다가 다시 포맷합니다.
무료인가요? 가입해야 하나요?
무료이고 계정도, 로그인도, 체험 기간도 없으며 얼마나 붙여 넣든 제한이 없습니다. 이 사이트에는 광고가 있고 그것이 비용을 댑니다. 광고에는 텍스트에 관한 것이 아무것도 주어지지 않습니다.
오프라인에서도 되나요?
됩니다. 페이지를 한 번 불러온 뒤 인터넷을 끊어도 계속 동작합니다. 이것이 아무것도 업로드되지 않는다는 가장 간단한 증명이기도 합니다. XML을 포맷하러 밖으로 보내는 도구라면 선을 뽑는 순간 멈췄을 것입니다.