Thanks for the effort. That does disperse crucial obscurity. A couple of comments are in order.
[2] As mentioned in [1], the way a "look-up" table constructed inside the xslt document cannot belong to the null namespace is still applicable. That defect is curable by simply adding some namespace specifically to the <string_replacement> block. I won't be doing this in this case of trying to "dynamically" setting up the table's value. It won't work that way. <xsl:value-of> or attribute value template won't help as they must be in some template called upon to make the evaluation. (If anything happens that make you think it work by hard coding the param or whatever..., it is just some kind of illusion.) There are some questionable constructions in the rest which may contribute to that illusion. But I am not going to specifically picking them one-by-one or to scrutinize them, that demands a lot of efforts and verbosity! (If one is determined to make that kind of construction work, one has to use some extension. I am quite sure it can be made with some effort, but I don't think it is particularly attractive to doing so.)
[3] As a quick and direct approach,
you should be able to do it like this within the realm of version 1.0 without using any xslt extension functionality.
[3.1] I would add mode attribute to isolate the specific processing need for that objective.
[3.2] With the above, the replacement of value for each placeholder is thorough, not restricted to a specific subset of them for a specific Template id...
[3.3] The placeholder can appear at multiple places in the text content.
[4] When think about it, the scripting of template to match the text() of mode="proc" is not less generally applicale as drafting a lookup table. It might look more laborious by cascading the replacement.