简体中文

语法转换器的作用

JSON、YAML、XML、TOML 和 CSV 不包含相同的内容。此页面准确说明了每个形状的映射方式、哪些转换是有损的,以及该工具拒绝执行哪些操作。

它转换什么

九种定向转换:JSON 到 YAML、YAML 到 JSON、JSON 到 XML、XML 到 JSON、JSON 到 TOML、TOML 到 JSON、YAML 到 TOML、TOML 到 YAML 以及 JSON 到 CSV。每个都在您的浏览器选项卡中运行;没有上传任何内容。

每个转换在内部都以相同的方式工作:将源文档读入普通的 JavaScript 值,然后以目标格式写出该值。 YAML 到 TOML 并不是一个特例,它是 YAML 读取器随后是 TOML 写入器。这就是为什么下面的警告是按格式而不是按对声明的 - 有关 TOML 日期时间的警告适用于 TOML 出现的任何地方。

CSV 是只写的,而且是故意这样的。读取 CSV 意味着猜测分隔符、引用方言、第一行是否是标题以及每个单元格的类型——四次猜测,每一次转换器都会悄悄出错。这是一个有要求的工具的工作。

XML:属性、数组和我们选择的规则

XML 没有规范的 JSON 映射,因此必须选择约定。只要 XML 是这两种格式之一,它们就在屏幕上可见,它们就是这些。

属性成为以 @ 为前缀的对象键。 <user id="7"><name>Ada</name></user> 读作 {"user":{"@id":"7","name":"Ada"}}。前缀可以防止同名的属性和子元素折叠成一个键 - <user id="7"><id>other</id></user> 保留两者。

也具有属性或子元素的元素内的文本位于#text 键下。仅包含文本的元素会折叠为该文本。 CDATA 部分位于 #cdata 下,因此其内容显然是数据而不是标记。

重复的同级元素成为一个数组。出现一次的元素名称不会变成数组 — XML 使解析器无法区分“包含一项的列表”和“单个值”,并且没有转换器可以发明该信息。如果您需要稳定的形状,那么这是模式的争论,而不是更聪明的转换器的争论。

命名空间前缀逐字保留:<ns:item> 是键 ns:item,xmlns:ns 是属性 @xmlns:ns。没有任何内容被解析、重写或剥离,因为解析前缀会丢弃文档实际包含的文本。

自闭合标签读作空字符串。 XML 声明、处理指令和注释均被删除。另一方面,该工具编写自己的声明,而不是 DOCTYPE。

编写 XML 时,如果键不是合法的 XML 元素名称(一个带有空格,一个以数字开头,一个以字母 xml 开头),则会按名称拒绝,而不是默默地重写。悄悄重命名的元素会生成一个没有任何验证的文档。

外部实体被拒绝,而不仅仅是被禁用

XML 文档可以声明 DOCTYPE 中的实体。扩展它们的解析器是 XXE 漏洞:声明为 SYSTEM“file:///etc/passwd”的实体读取本地文件,指向 URL 的实体发出攻击者控制的请求,而内部实体链是将几百字节变成千兆字节的“十亿笑声”拒绝服务。

此转换器不会将解析器配置为小心 DOCTYPE。在给解析器一个字节之前,它会拒绝任何包含该字节的文档,并且没有选项可以关闭拒绝。这使得保证成为我们代码的属性,而不是依赖项的默认设置 - 并且差异很重要,因为版本之间的默认值会发生变化,并且我们自己的拒绝被测试覆盖,这些测试为它提供每个标准 XXE 有效负载,并断言没有获取任何内容,也没有扩展任何内容。

实际成本:具有 DOCTYPE 的文档即使无害,也不会在此处进行转换。如果内容是您的,请删除 DOCTYPE。

TOML 日期时间在其他地方没有等效项

TOML 1.0 有四种时间类型,而 JSON、YAML 和 XML 没有:偏移日期时间 (1979-05-27T07:32:00Z)、本地日期时间(1979-05-27T07:32:00,故意没有区域),本地日期(1979-05-27)和本地时间(07:32:00)。

每个都变成与编写时完全相同的 RFC 3339 字符串,并且转换会告诉您它对哪些值执行了此操作以及每个值属于四种类型中的哪一种。另一种选择是为所有四个时间发出一个 UTC 时刻,将当地时间移动到文档明确拒绝声明的区域,这是一个错误的答案,而不是一个有损的答案。

转换回来会产生带引号的字符串,而不是日期时间。因此,TOML 到 JSON 到 TOML 的往返会更改这些值的类型。如果不发明一种接收工具必须共享的约定,就无法解决这个问题,而默默地发明一种约定会更糟。

TOML 整数有符号 64 位; JSON 数字是 IEEE-754 双精度数。超过 2^53 - 1 的整数将成为一个字符串,并在警告中指定路径,而不是因舍入而丢失最后一位数字,而您不会注意到。

TOML 没有 null。输出中省略了空键并在警告中命名;数组中的 null 会变成空字符串,因为删除它会移动后面的每个索引。 TOML 文档的根始终是一个表,因此根处的数组或裸值会被拒绝,并用一句话说明原因。

YAML:锚点、流和挪威问题

YAML 使用受限模式读取,只能生成字符串、数字、布尔值、null、列表和映射。构造任意对象的标签 - !!js/function、!!python/object/apply、!!binary - 被拒绝,这就是限制存在的全部原因:尊重它们的加载器是一个穿着配置文件衣服的任意对象构造函数。

锚点和别名被解析为重复的数据。一旦跟随其别名,文档的值就会扩展超过一百万个值,该文档将被拒绝,而不是允许冻结选项卡;递归别名被彻底拒绝,因为这里没有其他格式可以表达循环。

由 --- 分隔的多个文档的流成为文档数组,转换也是如此。此工具中没有其他格式具有流,因此数组是唯一诚实的映射。

YAML 禁止重复的映射键,并且每个解析器的处理方式都不同。该工具保留最后一个值(JSON.parse 使用的规则)并告诉您它发生了,以及重复的位置。默默地丢弃文件会更糟;默默地选择一个值而不说出来会更糟。

挪威问题:在 YAML 1.1 中,未加引号的标量 y、yes、on、no、off 和国家代码 NO 都解析为布尔值,这就是国家代码列表变成 true 和 false 列表的方式。该工具读取 YAML 1.2,其中只有 true 和 false 是布尔值,因此 NO 保留字符串 NO。当它编写 YAML 时,它会引用 1.1 解析器会误读的每个字符串 - 'NO'、'yes'、'on'、'1.0'、'0755'、'2001-12-14' - 因此输出可以安全地提供给尚未移动到的工具1.2。这会花费一些引号字符并购买正确性。

看起来像数字的字符串出于同样的原因保留其引号:“0755”保留字符串而不是成为 755,“1.0”保留字符串而不是成为 1。

评论在各个方面都消失了。 JSON、CSV 等没有地方放它们,也无法猜测它们应该返回哪里。

JSON 到 CSV:扁平化和停止公式的撇号

数组变成行,每个元素一条记录。单个属性包含数组的对象使用该数组作为行,因为 {"users": [ ... ]} 绝大多数是带有标签的表 - 并且转换大声表明它做到了这一点。任何其他对象都是单行。拒绝裸露的字符串、数字或空值:矩形需要记录。

嵌套对象和数组被展平为点列名称,其中对象键和数组索引都用点表示:address.city、tags.0、tags.1。一个分隔符,一条规则。已经包含点的键使其列名与嵌套路径不明确;该工具会发出警告,而不是发明一个电子表格无法理解的转义方案。

每一行的键都按首次出现的顺序联合起来。缺少字段的行会得到一个空单元格而不是移位的列,并且转换会警告行不规则。一个空对象或空数组将成为其自己路径下的一个空单元格,而不是消失。

引用遵循 RFC 4180:包含分隔符、双引号、CR 或 LF 的字段用双引号括起来,嵌入的引号会写入两次。记录由 CRLF 分隔。带有前导或尾随空格的字段也会被引用,因为电子表格会默默地修剪它们。 Unicode 不变地通过,并且可以为需要读取 UTF-8 的电子表格添加字节顺序标记作为前缀。

配方注射剂是最令人痛苦的一种。文件打开时,以 =、+、-、@、制表符或回车符开头的单元格将由 Excel、LibreOffice Calc 和 Google Sheets 作为公式执行。 =cmd|'/c calc'!A1是大家引用的演示; =IMPORTXML(...) 是悄悄地将工作表发送到某处的那个。逐字写入此类字符串的转换器已将您的数据转换为其他人的代码执行,在一个看起来惰性的文件中。

因此,以这些字符之一开头的文本单元格带有撇号前缀,每个主要电子表格都将其读作“这是文本”,并且不会显示在单元格中。数字不用管:数字 -5 是一个数字,而不是一个公式。报告逃逸单元的计数,并且可以关闭逃逸 - 在这种情况下,该工具会清楚地说明您刚刚关闭的内容。

CSV 无法区分空字符串和 null。两者都变成空单元格,并且转换会计算空值,以便您知道它发生了。

限制以及当您达到限制时会发生什么

每种格式都有字符上限,在下载解析器之前就强制执行:JSON 为 8 百万,XML 和 CSV 源为 4 百万,YAML 和 TOML 为 2 百万。除此之外,该工具会拒绝提供确切的数字,而不是成为一个无响应的选项卡,从而丢失您粘贴的内容。

CSV 输出还受到 100,000 行和 2,000 列的限制,因为深度嵌套的数组会展平为每个元素一列,并且几兆字节的 JSON 可能会成为电子表格无法打开的表格。

空和仅空白输入将报告为空,而不是转换为 null 或空文档。所有四种可读格式中的行和列都会报告无效语法。

仅当转换需要解析器时才会下载解析器本身。打开工具包来解码 JWT 不会获取任何内容。

你粘贴的内容会发生什么

  • 每个转换、哈希、解码和差异都在您的浏览器选项卡中运行。不会在服务器上上传、记录或存储任何输入,因为页面加载后就不再涉及服务器。
  • 哈希值来自浏览器自己的 Web Crypto 实现,UUID 来自其加密安全随机生成器。两者都不涉及网络调用。
  • 您键入的任何内容都不会写入本地存储或 cookie。重新加载页面会丢弃它;关闭选项卡将丢弃它。
  • 站点范围的分析仅在配置的规范生产主机上运行,并在隐私政策中披露;本地和预览主机拒绝它。粘贴的值、令牌、URL 和文件内容不包括在 ToolAcre 自己的分析事件中。当前配置中禁用广告。
  • 也就是说:JWT 或 API 密钥是实时凭证。安全的习惯是永远不要将其粘贴到不是您编写的网页中,无论其声明多么可信 - 包括这个。

问题

为什么我的 XML 文档失败并显示“声明 DOCTYPE”?

因为它包含文档类型声明,并且此转换器拒绝其中的每一个,而不是信任解析器设置来安全地处理实体。如果内容是您的,请删除 DOCTYPE。没有选项允许它。

为什么我的 TOML 日期时间返回为带引号的字符串?

因为 JSON、YAML 和 XML 没有日期类型。日期时间被转换为 RFC 3339 文本,它是所有其他格式的字符串。因此,转换回来会产生一个字符串,并且该工具会在发生这种情况时向您发出警告,而不是让您稍后发现。

为什么我的 CSV 单元格之一以撇号开头?

因为它的文本以=、+、-、@、制表符或回车符开头,而电子表格在打开文件时将此类单元格作为公式执行。撇号将单元格标记为文本;一旦单元格被读取,它就不再是值的一部分。您可以关闭转义,该工具会告诉您这意味着什么。

为什么单个重复的 XML 元素不是数组?

因为 XML 无法提供区分一列表和单个值的方法。两者写法相同。在任何一个方向上进行猜测都有可能是错误的,因此该工具会报告实际存在的内容。

我可以在这里将 CSV 转换回 JSON 吗?

不能。正确读取 CSV 需要决定分隔符、引用方言、第一行是否为标题以及每个单元格的类型。猜测所有四个的转换器都会悄悄地出错,这是最糟糕的错误方式。使用要求的 CSV 工具。

为什么“NO”没有转换为 false?

因为该行为属于 YAML 1.1 并且此工具读取 YAML 1.2,其中只有 true 和 false 是布尔值。 1.1 行为是挪威国家代码在配置管理中成为笑话的原因。当该工具编写 YAML 时,它会引用此类字符串,因此下游的 1.1 解析器也不会误读它们。

局限性

  • CSV 是写入的,从未读取过。这里没有选择将 CSV 转换为 JSON。
  • 评论在各个方向、各种格式中都会丢失。
  • TOML 日期时间变成所有其他格式的字符串,因此 TOML 往返会更改这些类型。不存在无损路径。
  • 包含 DOCTYPE 的 XML 文档将被彻底拒绝,包括无害的文档,并且拒绝无法关闭。
  • 单个重复的 XML 元素无法与非重复的元素区分开来,因此 XML 到 JSON 到 XML 并不总是返回原始形状。
  • XML 混合内容(与子元素交错的文本)会丢失文本相对于子元素的位置,并且无法往返。
  • 除非打开类型推断,否则 XML 值都是字符串,因为 XML 不声明任何类型;根据推断,“0755”和“NO”会受到通常的误读。
  • TOML 没有 null:空键从 TOML 输出中删除,数组内的 null 变为空字符串。
  • TOML 文档的根必须是表,因此 JSON 数组或标量根本无法转换为 TOML。
  • JSON 数字是 IEEE-754 双精度数。 2^53 之后的整数将转换为字符串,而不是静默舍入,这会改变它们的类型。
  • CSV 无法区分空字符串和 null;两者都被写为空单元格。
  • CSV 扁平化对对象键和数组索引都使用点,因此已经包含点的键会产生不明确的列名称,该名称会被警告但不会转义。
  • YAML 锚点和别名被解析而不是保留;输出没有锚点,并且拒绝递归别名,因为没有目标格式可以表达循环。
  • 每种格式的输入都有上限——JSON 8 百万个字符,XML 4 百万个字符,YAML 和 TOML 2 百万个字符——并且过大的文档会被拒绝而不是缓慢处理。
  • 这里没有任何内容根据模式进行验证。文档可以干净利落地转换,但对于其目的来说仍然是错误的。