xmlxq

How to parse XML into JSON with xq and output specific elements as numbers? (instead of strings)


I'm not too well versed when it comes down to xq/jq... I've been trying to parse something like this:

<?xml version="1.0"?>
<groups>
  <a>
    <count>1</count>
    <max>46</max>
    <name>foo</name>
  </a>
  <a>
    <count>3</count>
    <max>81</max>
    <name>bar</name>
  </a>
</groups>

into this: (note the lack of double quotes around the numbers)

[
  {
    "count": 1,
    "max": 46,
    "name": "foo"
  },
  {
    "count": 3,
    "max": 81,
    "name": "bar"
  }
]

I understand that a priori xq has no way to discard what is a number and what is a string. So I tried a few jq artifacts using 'select' among others but I couldn't make it work... so for now I'm bound to remove the double quotes with 'sed'... which I find very inelegant knowing that xq could easily do it.

Would anybody know the parameters to pass to xq in order to look for specific elements (i.e. 'count' & 'max') and apply a transformation (i.e. 'tonumber') only to those elements while leaving the rest of the elements untoched?

Thanks a lot in advance!


Solution

  • Since xq bundled along with kislyuk/yq uses jq underneath for DSL, you can use the tonumber function to convert the .count to their numeric equivalent

    xq '.groups.a | map( (.count, .max) |= tonumber )' xml
    [
      {
        "count": 1,
        "max": 46,
        "name": "foo"
      },
      {
        "count": 3,
        "max": 81,
        "name": "bar"
      }
    ]