title: Restrict a string to whitelisted characters using XSLT 1.0
body: <h2>Question</h2>
  
  <p>Using XSLT 1.0, given a string with arbitrary characters how can I get back a string that meets the following rules.</p>
  
  <ol>
  <li>First character must be one of these: a-z, A-Z, colon, or underscore</li>
  <li>All other characters must be any of those above or 0-9, period, or hyphen</li>
  <li>If any character does not meet the above rules, replace it with an underscore</li>
  </ol>
  
  <h2>Background</h2>
  
  <p>In an XSLT I'm translating some attributes into elements, but I need to be sure the attribute doesn't contain any values that can't be used in an element name.  I don't care much about the integrity of the attribute being converted to the name as long as it's being converted predictably.  I also don't need to compensate for <em>every</em> valid character in an element name (there's a bunch).</p>
  
  <p>The problem I was having was with the attributes having spaces coming in, which the translate function can easily convert to underscores:</p>
  
  <pre><code>translate(@name,' ','_')
  </code></pre>
  
  <p>But soon after I found some of the attributes using slashes, so I have to add that now too.  This will quickly get out of hand.  I want to be able to define a whitelist of allowed characters, and replace any non-allowed characters with an underscore, but translate works as by replacing from a blacklist.</p>