Boyd
Boyd

Reputation: 451

Adding items with default values to empty array with yq (go)

ok I've been in contact with chatgpt and gemmini on this and they are really out to lunch a lot of the time.

I am using https://github.com/mikefarah/yq

I am reading from xml and need to ensure single items are arrays, and I have been successful at that with several objects including:

.xdxf.lexicon.ar[].def[].def[].def[0].def[].ex |= ([] + .)

I can check the data with (note the 3rd def[0])

.xdxf.lexicon.ar[].def[].def[].def[0].def[] 
deftext: district
sr:
  kref: "null"
categ: "null"
ex: []
deftext: revue
ex:
  - +@type: exm
    +@author: ""
    +@source: ""
    ex_orig: kɔrɔman
    ex_tran: ancien

that shows both added empty arrays and existing arrays. But the problem is some of the items in ex[] are mandatory, so I want to populate ex[] with +@type: exm to get me started.

I have tried many syntax variations each with //, select and unique. Either the comands hang or are not returning any or bad data. I don't want to have any ex: [] as in the output above. I want to have at minimum:

ex:
  - +@type: exm

Samples of what i have tried:

.xdxf.lexicon.ar[].def[].def[].def[0].def[].ex = (.xdxf.lexicon.ar[].def[].def[].def[0].def[].ex + [{"+@type": "exm"}] | unique)

.xdxf.lexicon.ar[].def[].def[].def[0].def[].ex // [] | .xdxf.lexicon.ar[].def[].def[].def[0].def[].ex += [{"@type":"exm"}]

.xdxf.lexicon.ar[].def[].def[].def[0].def[].ex // .xdxf.lexicon.ar[].def[].def[].def[0].def[].ex += [{"@type":"exm"}]

.xdxf.lexicon.ar[].def[].def[].def[0].def[] | select(.key == "ex" and . == []) | . |= { ex: [{"@type":"exm"}] }

Upvotes: 0

Views: 261

Answers (1)

Boyd
Boyd

Reputation: 451

I was able to solve this issue as follows:

 .xdxf.lexicon.ar[].def[].def[].def[0].def[].ex |= ([] + .) | 
  .xdxf.lexicon.ar[].def[].def[].def[0].def[].ex[0].+@type // "foo" |= . |
  .xdxf.lexicon.ar[].def[].def[].def[0].def[].ex[0].ex_orig // "bar" |= . |
 .xdxf.lexicon.ar[].def[].def[].def[0].def[].ex[0] |= select(.["+@type"] == null) |= .ex_orig = "" |
 .xdxf.lexicon.ar[].def[].def[].def[0].def[].ex[0] |= select(.ex_orig == "") |= .+@type = "exm"

First line converts .ex object to arrays and adds empty array where no object exist.

Second and third lines test if the needed array items exist. This only worked for me by specifying the [0] of the empty array. foo bar has no effect but this at least adds the needed items albeit with a null value. I could not find a way to add these items with a value.

Forth and fifth lines select one item while changing the value of the other. I also found no documentation explaining if or how you can select an item by value and change the value.

Upvotes: 0

Related Questions