Search code examples
bashjqxq

How to make Jq return always in array


My input may be:

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>UserTriggerHandler_Test</members>
        <members>UserTriggerHandasdler_Test</members>
        <name>ApexClass</name>
    </types>
    <version>52.0</version>
</Package>

Or

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
        <members>UserTriggerHandasdler_Test</members>
        <name>ApexClass</name>
    </types>
    <version>52.0</version>
</Package>

Xp value for these are :

{
    "Package": {
        "@xmlns": "http://soap.sforce.com/2006/04/metadata",
        "types": {
            "members": "UserTriggerHandasdler_Test",
            "name": "ApexClass"
        },
        "version": "52.0"
    }
}

and

{
    "Package": {
        "@xmlns": "http://soap.sforce.com/2006/04/metadata",
        "types": {
            "members": ["UserTriggerHandler_Test", "UserTriggerHandasdler_Test"],
            "name": "ApexClass"
        },
        "version": "52.0"
    }
}

Respectively.

And I am trying to pass the input to this function.

classsvalue=`cat manifest/package.xml | xq . | jq '.Package.types | if type=="array" then .[] else . end | select(.name=="ApexClass") |select(.members!="Test")|.members | join(",")'`
echo $classsvalue

But it fails because of join(","). I want to force jq to always return members in an array. Is this possible?

I am expecting out put as "UserTriggerHandasdler_Test" and "UserTriggerHandasdler_Test,UserTriggerHandasdler_Test" respectively.


Solution

  • What you're asking for isn't really an array, so I'm ignoring that part of the question.

    # Original, unmodified code here
    .Package.types |
    if type=="array" then .[] else . end |
    select(.name=="ApexClass") |
    select(.members!="Test") |
    .members |
    # New code here
    if type == "string" then [.] else . end | join(",")
    

    That last line is the critical part -- wrapping the result in a list, should it be a string, before doing the join().