将 xml 转换为 json 的脚本

Sil*_*ver 2 scripting ubuntu xml text-processing json

我在 txt 文件中有 5000 个问题,如下所示:

<quiz>
        <que>The question her</que>
        <ca>text</ca>
        <ia>text</ia>
        <ia>text</ia>
        <ia>text</ia>
    </quiz>
Run Code Online (Sandbox Code Playgroud)

我想在 Ubuntu 中编写一个脚本来转换所有问题,如下所示:

  {
   "text":"The question her",
   "answer1":"text",
   "answer2":"text",
   "answer3":"text",
   "answer4":"text"
  },
Run Code Online (Sandbox Code Playgroud)

Dmi*_*try 6

事实上,即使没有 Python 编程,你也可以摆脱这里,只需使用 2 个 unix 实用程序:

  1. jtm- 允许 xml <-> json 无损转换
  2. jtc- 允许操作 JSON

因此,假设您的 xml 位于 中file.xml,jtm 会将其转换为以下 json:

bash $ jtm file.xml 
[
   {
      "quiz": [
         {
            "que": "The question her"
         },
         {
            "ca": "text"
         },
         {
            "ia": "text"
         },
         {
            "ia": "text"
         },
         {
            "ia": "text"
         }
      ]
   }
]
bash $ 
Run Code Online (Sandbox Code Playgroud)

然后,应用一系列 JSON 转换,您可以得到所需的结果:

bash $ jtm file.xml | jtc -w'<quiz>l:[1:][-2]' -ei echo { '"answer[-]"': {} }\; -i'<quiz>l:[1:]' | jtc -w'<quiz>l:[-1][:][0]' -w'<quiz>l:[-1][:]' -s | jtc -w'<quiz>l:' -w'<quiz>l:[0]' -s | jtc -w'<quiz>l: <>v' -u'"text"'
[
   {
      "answer1": "text",
      "answer2": "text",
      "answer3": "text",
      "answer4": "text",
      "text": "The question her"
   }
]
bash $ 
Run Code Online (Sandbox Code Playgroud)

不过,由于涉及 shell 脚本(echo命令),它会比 Python 慢 - 对于 5000 个问题,我预计它会运行大约一分钟。(在未来的版本中,jtc我计划甚至在静态指定的 JSON 中也允许插值,这样模板化就不需要外部 shell 脚本了,那么操作将会非常快)

如果您对jtc语法感到好奇,可以在这里找到用户指南: https: //github.com/ldn-softdev/jtc/blob/master/User%20Guide.md


Kus*_*nda 5

https://kislyuk.github.io/yq/xq中的工具将您的 XML 转换为

{
  "quiz": {
    "que": "The question her",
    "ca": "text",
    "ia": [
      "text",
      "text",
      "text"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

只需使用恒等过滤器 ( xq . file.xml) 即可。

我们可以将其按摩成更接近您想要使用的形式

xq '.quiz | { text: .que, answers: .ia }' file.xml
Run Code Online (Sandbox Code Playgroud)

哪个输出

{
  "text": "The question her",
  "answers": [
    "text",
    "text",
    "text"
  ]
}
Run Code Online (Sandbox Code Playgroud)

要修复该answers位以便获得枚举键:

xq '.quiz |
    { text: .que } +
    (
        [
            range(.ia|length) as $i | { key: "answer\($i+1)", value: .ia[$i] }
        ] | from_entries
    )' file.xml
Run Code Online (Sandbox Code Playgroud)

这通过迭代节点并手动生成一组键和值来添加枚举键和answer来自节点的值。然后使用它们将它们转换为真正的键值对,并将其添加到我们创建的原始对象 ( ) 中。iaiafrom_entries{ text: .que }

输出:

{
  "text": "The question her",
  "answer1": "text",
  "answer2": "text",
  "answer3": "text"
}
Run Code Online (Sandbox Code Playgroud)

如果您的 XML 文档quiz在某个根节点下包含多个节点,则将上面的表达式更改为.quiz对每个节点进行转换,并且您可能希望将结果对象放入数组中:jq.[].quiz[]

xq '.[].quiz[] |
    [ { text: .que } +
    (
        [
            range(.ia|length) as $i | { key: "answer\($i+1)", value: .ia[$i] }
        ] | from_entries
    ) ]' file.xml
Run Code Online (Sandbox Code Playgroud)