Use XPath to Concatenate Strings (Cleaner)

There have been times when you may need to take a list of strings and concatenate them together into a single string.

Think of a list of email address, concatenated by a semi-colon (;) like so:

As I’ve recently mentioned, loops can be slow … and the output messy, even with a simple “Append to string variable” action.

Just look at the output, double semi-colons (;;) where the blank values used to be … yucky!

clark.kent@dailypla.net;;lois.lane@dailypla.net;jimmy.olsen@dailypla.net;;perry.white@dailypla.net

Even the Data Operation action Join, while easier/faster that the loop, is still messy!

Same messy output as the loop, just faster.

I know what you’re thinking, it’s just a list of email addresses, double semicolons don’t really matter. True, but if you’re exporting the value to another system or doing some other processing on it, it may actually matter, especially if it’s some other value besides email addresses. Plus, nice-n-tidy clean strings are better to deal with. So …

XPath to the rescue!

Here’s how XPath can be used to make the output cleaner (and just as fast as the Join).

Using XPath’s translate(…) and normalize-space() functions

The key here is the combination of the translate(...) and normalize-space() XPath functions.

normalize-space() – grabs the text value from all nodes, reduces multiple spaces to a single space, then removes all beginning/trailing spaces from the final concatenated text value.

translate(...) – replaces the search character(s) with the specified character(s).

One thing to note here about the normalize-space() function. Since beginning/trailing spaces are removed, the text values are shoved together, like this:

clark.kent@dailypla.netlois.lane@dailypla.netjimmy.olsen@dailypla.netperry.white@dailypla.net

Shucks, now we don’t know where one value ends and the next begins.

To fix this, we simply inject in a trailing space after each value.

The XML will initially look like this

<r>
  <v>clark.kent@dailypla.net</v>
  <v>lois.lane@dailypla.net</v>
  <v>jimmy.olsen@dailypla.net</v>
  <v>perry.white@dailypla.net</v>
</r>

and after this expression to inject the trailing space

replace(string(xml(json(concat('{"r":{"v":', outputs('Strings'), '}}')))), '</v>', ' </v>')

the new XML will look like this (trailing spaces highlighted in blue)

<r>
  <v>clark.kent@dailypla.net </v>
  <v>lois.lane@dailypla.net </v>
  <v>jimmy.olsen@dailypla.net </v>
  <v>perry.white@dailypla.net </v>
</r>

Here is the complete XPath expression and the output:

xpath(xml(replace(string(xml(json(concat('{"r":{"v":', outputs('Strings'), '}}')))), '</v>', ' </v>')), 'translate(normalize-space(), " ", ";")')
Nice clean output of the XPath expression

Lastly, to show you how well the XPath vs Join vs loop performs:

Happy coding!


Follow My Blog

Get new content delivered directly to your inbox.

Author: Joey

I develop modern solutions leveraging the Microsoft cloud technologies: Power Platform and SharePoint Online, with a focus on process automation. I got my start writing code professionally beginning with Microsoft VB6, but really fell in love with code (and the art of it) with Microsoft .NET Framework version 1.0. I'm also a fan of Superman, so don't be surprised if references creep in. Up, Up, and Away!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: