Forum Discussion
Hey @alex.panganiban.guild . Hope you’ve been well too. I will look at this today.
@mbowen Good Morning, Matthew. Well, I came up with a solution, yet I still don’t understand how this expression works. I just blindly and dumbly followed the pattern more closely. Mostly the whole (_matched, prefix, b64enc) callback function escapes my comprehension. This is what I finally came up with and it seems to work. If I have any new custom attributes in the future that contain HTML entity codes, I can just add them to prefix options in this expression.
$content.replace(/<(short|long)-description>(.+?)</\1-description>/g,
(_matched, prefix, b64enc) => “<”+prefix+“-description>”+Base64.decode(b64enc)+“</”+prefix+“-description>”).replace(/(productFeatures|anyNewCustomAttributeWithEncodedHTMLAddHere)">(.+?)</custom-attribute>/g, (_matched, prefix, b64enc) => prefix + “">” + Base64.decode(b64enc) + “”)
- mbowen4 years agoEmployee
Wonderful, but yikes. Ok, let me parse your expression and we’ll explain together.
- alex_panganiban4 years agoContributor
@mbowen Haha, I know it looks scary, but hey, when you originally came up with this solution, I thought it was brilliant and imaginative…and I still do. It works wonderfully and it solved the HTML entity problem I was having with XML. And we were able to do it without having to complicate doctypes and DTD’s. So kudos to you. Now I just wish I comprehended how it works.
I will add, I had to place the element’s value in a CDATA wrap in order to get the XML document to import into Salesforce successfully. Before I did that, the Salesforce XML validation process was also flagging my undeclared HTML entity codes and rejecting my import.
What I ended up finally importing, after Base64 decoding my value with the replacement expression, looked something like what’s below. I did the same wrap thing with the short and long descriptions that we worked on earlier this summer as well.
<custom-attribute attribute-id=“productFeatures”><![CDATA[<p>Features List ™</p>]]></custom-attribute>
- mbowen4 years agoEmployee
Your final xml payloads were pretty big (lots of text), so I think we want to be as precise as possible when replacing text to prevent accidentally replacing something. So, we may want to tighten up the custom-attribute match. Here’s a slightly different version from what you have:
$input .replace(/<(short|long)-description>(.+?)<\/\1-description>/g, (_matched, prefix, b64enc) => "<" +prefix+ "-description>" +Base64.decode(b64enc)+ "</" +prefix+ "-description>") .replace(/<custom-attribute attribute-id="(productFeatures|attr-x)">(.+?)<\/custom-attribute>/g, (_matched, attrid, b64enc) => '<custom-attribute attribute-id="' +attrid+ '">' +Base64.decode(b64enc)+ '</custom-attribute>')
Javascript regular expressions are “greedy” by default so will try to match as much as possible. We want to match the nearest closing element, so want to use a reluctant quantifier which is what the question mark will do. That is,
(.+) // greedy (.+?) // reluctant (not greedy)
I think we need to escape the forward slash in the regex, for both replace methods. (ie, /). I put a grouping in the attribute-id with “attr-x” meant to convey your anyNewCustomAttributeWithEncodedHTMLAddHere. You could add other attributes as needed (pipe delimited).
This appears to work. I’ve attached my test pipeline which contains a json payload in a JSON generator from an earlier payload that you had shared with me.
Thanks for sharing about having to CDATA encode data for Salesforce. Sheesh. So, many transformations.