0

I'm working with some JSON data in PowerShell. Some elements are multi-valued, delimited with a semi-colon, but its not always the same elements that are multi-valued. I would like to convert multi-valued elements, where ever they may occur, into JSON arrays.

I'm having trouble doing this. I've worked out a way to identify which elements are multi-valued, but am unsure how to split them when outputting the entire JSON. Do I need to construct a custom PSObject and breakout multi-valued elements into an array before exporting as JSON? That seems like a lot of overhead for a simple task.

Starting example

{
  "Title": "Civil War Diary - Original and Transcript",
  "Date Created": "1863",
  "Access Rights": "Open Access",
  "Identifier": "e9f44e22b9a285c1c3e2ac0307d113f3",
  "Resource Type": "Text; Still Image"
}

Desired output

{
    "Title": "Civil War Diary - Original and Transcript",
    "Date Created": "1863",
    "Access Rights": "Open Access",
    "Identifier": "e9f44e22b9a285c1c3e2ac0307d113f3",
    "Resource Type": [
        "Text",
        "Still Image"
    ]
}
5
  • What kind of object are you outputting the entire JSON from? What stops you from literally assigning an array to "Resource Type"? Commented Oct 27, 2021 at 16:22
  • The data starts out as a CSV that I'm importing. I have code now that converts this to the starting example above. I don't want to literally make "Resource Type" an array in all cases because many times it may only contain a single value -- I need to detect which properties are multi-valued for each JSON object.
    – Nathan
    Commented Oct 27, 2021 at 16:27
  • 1
    That doesn't sound like good API design, to be honest -- not only is such "detection" extra work for you, but in many languages it adds extra work on the consumer side as well, for no real benefit. (For example in python, if I do for res_type in data["Resource Type"] and it's suddenly a flat string, I end up iterating over each individual letter...) If a field can be a list, it should just always be a list. Commented Oct 27, 2021 at 16:40
  • I get what you're saying, but this isn't an API and I'm working with existing CSV data that has been created over 30 years for millions of items. I have to convert this data into the JSON as described above. So far my approach has been less object-oriented and more data transformation, might have to rethink that.
    – Nathan
    Commented Oct 27, 2021 at 17:52
  • Something else will later use the JSON data -- that makes its format an API in a sense, independently of whether it's going to be served via HTTP calls or not, and the same problems (i.e. needing additional type checks on both producer and consumer) apply in all cases. Commented Oct 27, 2021 at 17:56

1 Answer 1

0

As mentioned in the comments above, this data originates as a CSV file. I was able to add three lines to a ForEach-Object loop where I was trimming the fields to cast multi-valued fields to an array, split on the delimiter.

$csv | Foreach-Object {
    foreach ($property in $_.PSObject.Properties) {
        # Cast multi-valued fields to an array
        if ($property.value -like "*;*") {
            $property.value = [array]$property.value.Split(";")
        }
        # Trim fields
        $property.value = $property.value.trim()
    }
}
2
  • Just curious. Are you saying what you posted as an answer is working? As I cannot see how it is since there is no trim method possible relative to this line; $property.value = $property.value.trim(). So, did you mean to add this to your original post for folks to follow, or are you doing other stuff you are not showing?
    – postanote
    Commented Oct 28, 2021 at 0:55
  • Yes, this is working for me. (Will select as right answer when the 2-days pass.) I've long used the .trim method: adamtheautomator.com/powershell-trim/#Trimming_Whitespace. The trim was working long before splitting into an array. This code block is higher up in my script while I'm still dealing with CSV data, before I convert it to JSON.
    – Nathan
    Commented Oct 28, 2021 at 12:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .