A different tool, also called yq, uses a jq-like syntax and has better support for translating between XML and JSON. You can download the latest release from the Releases page. Unlike kislyuk's yq/xq it does not actually use jq for its processing, so you may have to adjust your jq scripts somewhat.

With mikefarah's yq, one can use the following command to regenerate the XML:

./yq_linux_amd64               \
    --xml-attribute-prefix @   \
    --xml-content-name '#text' \
    --input-format yaml        \
    --output-format xml        \
    security-settings.yaml

The very same command works for the JSON inputs as well, since JSON is a subset of YAML.

Arch Linux: Install the package go-yq to install the yq executable.

Answer from Gullah Geechee on Stack Overflow
🌐
Ashby
ashbyhq.com › blog › engineering › jq-and-yq
Querying JSON and XML with jq and xq | Ashby
January 9, 2022 - 1cat feed.xml | xq '.source.job[].country | length' | less · That's right! xq and jq have their own operators, which you can pipe output to within the command. The operator above will output the length of each country, and looking at the output, we can see that we're getting 0s where we had nulls before, and 2s for most things (phew!).
🌐
GitHub
github.com › kislyuk › yq
GitHub - kislyuk/yq: Command-line YAML, XML, TOML processor - jq wrapper for YAML/XML/TOML documents · GitHub
The yq package installs an executable, xq, which transcodes XML to JSON using xmltodict and pipes it to jq. Roundtrip transcoding is available with the xq --xml-output/xq -x option.
Starred by 2.9K users
Forked by 86 users
Languages   Python 94.7% | Makefile 5.3%
🌐
Substack
codefaster.substack.com › p › mastering-jq-xml-and-any-other-data
Mastering jq: xml (and any other data format)
July 7, 2020 - In this section, we’ll use jq to transform xml data. Consider the following data and let it be stored in before.json: { "root": { "a": [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] } } and we need to double each number so it looks like: { "root": { "a": [ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 ] } } ... Let us consider the same problem, but the data is instead encoded as xml.
🌐
Medium
lovethepenguin.com › xq-or-how-to-use-jq-with-xml-files-c486390313ff
xq: or how to use jq with XML files | by Konstantinos Patronas | Medium
August 14, 2023 - JSON is currently more popular ... by many legacy applications would be nice to have a command line tool like jq to work with XML files? actually we have and is called xq and is a wrapper for jq which adds support for XML files, lets see how we can install xq and use it ...
🌐
Ubuntu
manpages.ubuntu.com › manpages › questing › man1 › xq-python.1.html
Ubuntu Manpage: xq - Command-line XML processor - jq wrapper for XML documents
usage: xq [options] <jq filter> [input file...] [--version] [jq_filter] [files ...] xq: Command-line XML processor - jq wrapper for XML documents xq transcodes XML documents to JSON and passes them to jq. See https://github.com/kislyuk/xq for more information.
Top answer
1 of 2
10

A different tool, also called yq, uses a jq-like syntax and has better support for translating between XML and JSON. You can download the latest release from the Releases page. Unlike kislyuk's yq/xq it does not actually use jq for its processing, so you may have to adjust your jq scripts somewhat.

With mikefarah's yq, one can use the following command to regenerate the XML:

./yq_linux_amd64               \
    --xml-attribute-prefix @   \
    --xml-content-name '#text' \
    --input-format yaml        \
    --output-format xml        \
    security-settings.yaml

The very same command works for the JSON inputs as well, since JSON is a subset of YAML.

Arch Linux: Install the package go-yq to install the yq executable.

2 of 2
6

jq:

"@"     as $attr_prefix |
"#text" as $content_key |

# ">" (only) needs to be escaped if preceded by "]]". We'll do it unconditionally.
# Some whitespace also needs escaping, at least in attribute. Not done here.
{ "&": "&amp;", "<": "&lt;", ">": "&gt;"    } as $escapes      |
{ "&": "&amp;", "<": "&lt;", "\"": "&quot;" } as $attr_escapes |

def text_to_xml:          split( "" ) | map( $escapes[.]      // . ) | join( "" );
def text_to_xml_attr_val: split( "" ) | map( $attr_escapes[.] // . ) | join( "" );

def node_to_xml:
   if type == "string" then
      text_to_xml
   else
      (
         if .attrs then
            .attrs |
            to_entries |
            map( " " + .key + "=\"" + ( .value | text_to_xml_attr_val ) + "\"" ) |
            join( "" )
         else
            ""
         end
      ) as $attrs |

      if .children and ( .children | length ) > 0 then
         ( .children | map( node_to_xml ) | join( "" ) ) as $children |
         "<" + .name + $attrs + ">" + $children + "</" + .name + ">"
      else
         "<" + .name + $attrs + "/>"
      end
   end
;

def fix_tree( $name ):
   type as $type |
   if $type == "array" then
      .[] | fix_tree( $name )
   elif $type == "object" then
      reduce to_entries[] as { key: $k, value: $v } (
         { name: $name, attrs: {}, children: [] };

         if attr_prefix then
            .attrs[ v
         elif content_key then
            .children += [ $v ]
         else
            .children += [ $v | fix_tree( $k ) ]
         end
      )
   else
      { name: $name, attrs: {}, children: [ . ] }
   end
;

def fix_tree: fix_tree( "" ) | .children[];

fix_tree | node_to_xml

Demo on jqplay


It's invoked using

jq -r 'above progam' file.json >file.xml

You can also place the program in a file (say json_to_xml.jq) and use the following:

jq -rf json_to_xml.jq file.json >file.xml

I took a two-step approach. I first convert the input to an unambiguous format, then converting this result to XML. These two steps could be merged. Here's is the result of the first conversion of the provided input:

{
  "name": "security-settings",
  "attrs": {
    "xmlns": "urn:activemq:core"
  },
  "children": [
    {
      "name": "security-setting",
      "attrs": {
        "match": "#"
      },
      "children": [
        {
          "name": "permission",
          "attrs": {
            "type": "createNonDurableQueue",
            "roles": "admins"
          },
          "children": []
        },
        {
          "name": "permission",
          "attrs": {
            "type": "deleteNonDurableQueue",
            "roles": "admins"
          },
          "children": []
        },
        {
          "name": "permission",
          "attrs": {
            "type": "manage",
            "roles": "admins"
          },
          "children": []
        }
      ]
    }
  ]
}

Note that the format into which the original XML was converted is lossy. For example, it loses the relative order of XML elements with different names. This means the output of the above program may differ from the original XML in significant ways. But there's no escaping that unless you use a JSON schema that's not lossy.

🌐
Michael Tsai
mjtsai.com › blog › 2023 › 01 › 03 › jq-and-xmlstarlet
Michael Tsai - Blog - jq and XmlStarlet
... XMLStarlet is a set of command line utilities (tools) which can be used to transform, query, validate, and edit XML documents and files using simple set of shell commands in similar way it is done for plain text files using UNIX grep, sed, awk, diff, patch, join, etc commands.
Find elsewhere
🌐
SANS
isc.sans.edu › diary › 30930
Why yq? Adventures in XML - SANS Internet Storm Center
May 16, 2024 - This is a standalone install on ... the binary and put it in your path ... yq is written to mimic jq like you'd expect from the name, but will take json, yaml, xml, csv and tsv files....
🌐
jq
jqlang.org › manual
jq 1.8 Manual
Calls tostring, see that function for details. ... Serializes the input as JSON. ... Applies HTML/XML escaping, by mapping the characters <>&'" to their entity equivalents &lt;, &gt;, &amp;, &apos;, &quot;.
🌐
Hacker News
news.ycombinator.com › item
I've recently had some fruitful interactions with jq. I found its functional nat... | Hacker News
July 17, 2023 - Now, everytime I've to scrape data from XML from the command line, I wish I had a tool to translate XML to json so that I could use jq on it, instead of having to wrangle with xmlstarlet
🌐
Dzu's Blog
blog.lazy-evaluation.net › posts › linux › jq-xq-yq.html
jq, xq and yq - Handy tools for the command line | Dzu's Blog
April 27, 2020 - Having installed yq with the Python packager pip, we get the yp binary for working with YAML files and the xq binary for XML. Using the jq manual, it is straightforward to apply it to GPX files in my collection. Here are a few examples intended to convey an idea of the possibilities.
🌐
GitHub
github.com › mikefarah › yq
GitHub - mikefarah/yq: yq is a portable command-line YAML, JSON, XML, CSV, TOML, HCL and properties processor · GitHub
A lightweight and portable command-line YAML, JSON, INI and XML processor. yq uses jq (a popular JSON processor) like syntax but works with yaml files as well as json, kyaml, xml, ini, properties, csv and tsv.
Starred by 15.1K users
Forked by 753 users
Languages   Go 90.6% | Shell 9.0%
🌐
Stack Overflow
stackoverflow.com › questions › 76455292 › problem-when-converting-json-to-xml-using-jq-and-xmlstarlet
Problem when converting JSON to XML using jq and xmlstarlet - Stack Overflow
I am trying to convert JSON file into XML using following command which used JQ and XMSTARTLET jq -r 'def walk(f): . as $in | if type == "object" then reduce keys_unsorted[] as $key (.; ....
🌐
Peteris
peteris.rocks › blog › modifying-xml-json-ini-configuration-files-without-sed
Modifying XML, JSON, INI configuration files without sed | peteris.rocks
April 14, 2017 - Let's imagine that you now have a configuration file in JSON. { "name": "something", "version": "0.0.0", "array": [1,2], "params": { "name1": "value1", "name2": "value2" } } You want to add a new field dependencies that is an empty array []. You can use jq which is like sed but for JSON.
🌐
How-To Geek
howtogeek.com › home › linux › how to convert xml to json on the command line
How to Convert XML to JSON on the Command Line
July 14, 2020 - Luckily, there's a utility that can convert XML to JSON, which is easier to work with, both in scripts and on the command line. You'll want to use a custom made utility for this, rather than trying to parse it with something like regex, which is a bad idea. There's a utility called xq that is perfect for this task. It's installed alongside ... Under the hood, this utility uses jq to handle working with JSON, so you'll need to download the binary, and move it to somewhere on your PATH (/usr/local/bin/ should work fine).
🌐
Kislyuk
kislyuk.github.io › yq
yq: Command-line YAML/XML/TOML processor
The yq package installs an executable, xq, which transcodes XML to JSON using xmltodict and pipes it to jq. Roundtrip transcoding is available with the xq --xml-output/xq -x option. Multiple XML documents can be passed in separate files/streams as xq a.xml b.xml.
🌐
jc
kellyjonbrazil.github.io › jc › docs › parsers › xml.html
jc | CLI tool and python library that converts the output of popular command-line tools, file-types, and common strings to JSON, YAML, or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.
CLI tool and python library that converts the output of popular command-line tools, file-types, and common strings to JSON, YAML, or Dictionaries. This allows piping of output to tools like jq and simplifying automation scripts.
🌐
yq
mikefarah.gitbook.io › yq › usage › xml
Working with XML | yq
In XML, if your array has a single item, then yq doesn't know its an array. This is how you can consistently force it to be an array.