如何用DataWeave 2.0实现扁平JSON到结构化映射?
Fixing Index Matching for Flat to Structured JSON in DataWeave 2.0
Got it, let's tackle this problem head-on. You're trying to turn a flat JSON (where each certificate's details are tagged with indices like _1, _2) into a neat array where each entry groups a certificate file with all its corresponding metadata—validity dates, issuer, subject, etc. The initial code probably had issues aligning the certificate files with their matching properties because of index mismatches, so here's how to fix that.
Step-by-Step Solution
First, let's break down what we need to do:
- Pull out all the certificate file entries from the input (like
certFile_1,certFile_5). - Grab the index number from each certificate key (so
certFile_1gives us1). - Use that index to fetch the exact matching metadata (like
validFrom_1forcertFile_1). - Bundle everything into structured objects and wrap them in an array.
Corrected DataWeave Code
%dw 2.0 output application/json --- // First, filter out only the certificate file entries input filterObject ((val, key) -> key startsWith "certFile_") // For each cert file, map it to a structured object with matching metadata mapObject ((certVal, certKey) -> { // Extract the index from the cert key (e.g., "certFile_5" → "5") index: (certKey splitBy "_" last) as Number, certFile: certVal, // Dynamically fetch matching metadata using the index validFrom: input["validFrom_" ++ (certKey splitBy "_" last)] default null, validTo: input["validTo_" ++ (certKey splitBy "_" last)] default null, issuer: input["issuer_" ++ (certKey splitBy "_" last)] default null, subject: input["subject_" ++ (certKey splitBy "_" last)] default null }) // Convert the mapped key-value pairs into a clean array pluck $
What's Fixed & Why It Works
- Accurate Index Extraction: Using
splitBy "_" lastgrabs the numeric suffix from the certificate key, so we're always matching the right metadata to the right cert file—even if indices skip numbers like_5instead of_3. - Dynamic Property Lookup: By building the metadata key with the extracted index (like
"validFrom_" ++ "5"), we pull exactly the data that belongs to that certificate. - Safe Fallbacks: Adding
default nullmeans if a metadata field is missing for a cert, it won't break the code—it'll just returnnullfor that field. - Clean Array Output:
pluck $turns the mapped object (which has keys likecertFile_1) into a simple array of certificate objects, which is exactly the structure you want.
Example Input & Output
Let's test this with a sample input to see it in action.
Sample Input
{ "certFile_1": "cert1.pem", "validFrom_1": "2023-01-01", "validTo_1": "2024-01-01", "issuer_1": "CA Corp", "subject_1": "example.com", "certFile_2": "cert2.pem", "validFrom_2": "2023-02-01", "validTo_2": "2024-02-01", "issuer_2": "Global CA", "subject_2": "test.org", "certFile_5": "cert5.pem", "validFrom_5": "2023-05-01", "validTo_5": "2024-05-01", "issuer_5": "Local CA", "subject_5": "internal.net" }
Expected Output
[ { "index": 1, "certFile": "cert1.pem", "validFrom": "2023-01-01", "validTo": "2024-01-01", "issuer": "CA Corp", "subject": "example.com" }, { "index": 2, "certFile": "cert2.pem", "validFrom": "2023-02-01", "validTo": "2024-02-01", "issuer": "Global CA", "subject": "test.org" }, { "index": 5, "certFile": "cert5.pem", "validFrom": "2023-05-01", "validTo": "2024-05-01", "issuer": "Local CA", "subject": "internal.net" } ]
Quick Notes
- If you don't need the
indexfield in your output, just delete that line from the mapped object. - Need to add more metadata fields (like
serialNumber_)? Just follow the same pattern:serialNumber: input["serialNumber_" ++ (certKey splitBy "_" last)] default null. - This works for any number of certificates, no matter if the indices are consecutive or not.
内容的提问来源于stack exchange,提问作者worldpeace-20
相关产品推荐
相关产品推荐

