1 选好要做的事
排法 压平之后还是同一份文档,只是去掉了每一个只为好看而存在的空格。
最外层元素的名字 XML 顶上只有一个元素,JSON 没有,所以得替它造一个。
2 贴进来
3 把结果带走
# XML 格式化 — 排开、压平,或者转成 JSON 排开了好读的 XML,压平了好发的 XML,还有两个方向的 JSON 转换。这些都不会粘进别人的服务器。 > 格式化、缩进和压缩 XML,把 XML 转成 JSON 或者把 JSON 转回 XML。解析器在你的浏览器里跑,什么都不上传,所以一个订阅源、一张发票或者一份配置文件永远不会离开你的设备。 这是一个浏览器交互工具,地址是 https://abox.tools/zh/xml-formatter/。文件在运行该浏览器的设备上处理。主动分享和可选联网功能都在页面上说明。下文是它的文字说明;使用工具请打开该地址。 ## 你的 XML 和 JSON **在浏览器里处理**,无须上传处理。 格式化和转换都是对一段字符串做算术,就在这里,在这个页面上。解析器是手写的,在 `src/shared/parse-xml.js` 里,除此之外再没有别的。这个工具压根就没有网络功能,没有要取的,也没有要发的。这一点在这里比“XML”这个词听上去更重要:以这个格式送过来的,多半是一张发票、一份银行流水、一份病历,或者一个头里带着某人凭据的 SOAP 请求。 - ✗ 不上传 - ✗ 不注册 - ✗ 无大小限制 - ✓ 断网可用 - ✓ 开源 ## 不上传就把 XML 格式化的步骤 1. **挑一件事做。** 两个标签页,一个输入框:*格式化*把 XML 排开或者压平,*转换*把它变成 JSON,或者把 JSON 变回 XML。你刚排开的那份 XML 就是你要转换的那份,不用粘两遍。 2. **粘进来,或者把文件放上去。** 能选中能复制的都行。把 `.xml`、`.svg`、`.rss` 或 `.xsd` 文件放到选择框上,你自己的浏览器会读它并填进输入框——这里没有上传这一步可以省略。 3. **选缩进,或者压平。** 两个空格、四个空格,或者一个制表符。压平之后还是同一份文档,只是去掉了每一个只为好看而存在的空格,结果里会说这省了多少字节。 4. **在出错的地方读错误。** 在这里失败的解析器会告诉你*哪个标签*没闭合,在第几行第几列,而不是“第 1 行出错”——浏览器一口气读完一份文档之后说的就是那句。点击*跳转到错误位置*就能回到输入中的对应位置。输入时,焦点会留在原处,直到你主动移动它。 5. **把结果拿走。** 复制,或者下载成文件,文件名按它出来的格式取。 ## 说得更细的版本 [如何格式化并检查 XML](https://abox.tools/zh/guides/format-and-check-xml/): 在本地格式化、压缩和检查 XML。定位解析错误,在转换为 JSON 前了解属性、文本和数组的映射。 ## 工具箱里还有 - [文本比对](https://abox.tools/zh/text-diff/): 两段文本进来,每处差异都被标出来,逐行、逐词。没有一个字被贴进别人的服务器。 - [Base64 编码解码](https://abox.tools/zh/base64/): Base64、百分号编码、HTML 实体、十六进制和反斜杠转义,双向都行。没有一个字被贴进别人的服务器。 - [文本与文件分享](https://abox.tools/zh/share-text/): 分享只活在这个打开的标签页里。读的人从你的浏览器直接取走加密内容,关掉标签页就结束——任何服务器上都不留一点东西。 - [二维码与条形码生成](https://abox.tools/zh/qr-barcode/): 打进去,就变成一个码。生成过程不往外送任何东西。 ## 常见问题 ### 我的 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"`。替你决定,就是凭空造出一条信息,然后它还会一路当作文件里本来就有的东西传下去。 - **Google 加载了什么,又没拿到什么。** 广告和统计脚本来自 Google,捐赠按钮来自 Buy Me a Coffee。它们谁也没拿到你文本里的一个字符。读它、解析它、写它的每一行代码,都从这个源提供,也都列在仓库里。 - **断网可用。** 拔掉网线,这个工具一点变化都没有,因为它里面本来就没有联网这一步。这是最简单的证明。 **你可以自己核对。**上面这些不用你信。这个页面是仓库里的模板和配置生成出来的,构建脚本你能读,也能自己跑一遍,跑出来的结果就提交在 `dist` 分支上。拿实际发给你的内容,跟你自己从源码构建出来的结果对一遍就知道了: https://github.com/A-Box-of-Tools/website 最值得先读的几个文件:`config/site.toml` 里是 Content-Security-Policy,告诉你哪个标签没闭合的解析器在 `src/shared/parse-xml.js`,XML 里每个值为什么都按字符串出来、而不是靠猜的,在 `src/convert.js`。
不上传就把 XML 格式化的步骤
- 挑一件事做。两个标签页,一个输入框:格式化把 XML 排开或者压平,转换把它变成 JSON,或者把 JSON 变回 XML。你刚排开的那份 XML 就是你要转换的那份,不用粘两遍。
- 粘进来,或者把文件放上去。能选中能复制的都行。把
.xml、.svg、.rss或.xsd文件放到选择框上,你自己的浏览器会读它并填进输入框——这里没有上传这一步可以省略。 - 选缩进,或者压平。两个空格、四个空格,或者一个制表符。压平之后还是同一份文档,只是去掉了每一个只为好看而存在的空格,结果里会说这省了多少字节。
- 在出错的地方读错误。在这里失败的解析器会告诉你哪个标签没闭合,在第几行第几列,而不是“第 1 行出错”——浏览器一口气读完一份文档之后说的就是那句。点击跳转到错误位置就能回到输入中的对应位置。输入时,焦点会留在原处,直到你主动移动它。
- 把结果拿走。复制,或者下载成文件,文件名按它出来的格式取。
说得更细的版本
如何格式化并检查 XML 在本地格式化、压缩和检查 XML。定位解析错误,在转换为 JSON 前了解属性、文本和数组的映射。
工具箱里还有
常见问题
我的 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 送出去格式化的工具,在你拔线的那一刻就停了。