title: How to create a HTML hex entity with XSLT
body: <p>I'm experimenting with writing an XSLT stylesheet to generate HTML from a Text encoded in XML according to TEI standard.</p>
  
  <p>Now, when it comes to special characters, I'm running into difficulties - here's an example:
  The word "ſem" (normalized "sem", old norse relative pronoun) would be encoded <code>&lt;g ref="#slong"/&gt;em</code>, which refers to the following declaration in the header:</p>
  
  <pre><code>&lt;glyph xml:id="slong"&gt;
     &lt;glyphName&gt;LATIN SMALL LETTER LONG S&lt;/glyphName&gt;
     &lt;mapping type="facs"&gt;U+017F&lt;/mapping&gt;
     &lt;mapping type="norm"&gt;s&lt;/mapping&gt;
  &lt;/glyph&gt;
  </code></pre>
  
  <p>Of course, the idea would be, to be able to look up the mappings for every glyph, and then display it accordingly.<br>
  E.g. if I wanted to have a stylesheet that shows a normalized rendering of the text, I'd have something like</p>
  
  <pre><code>&lt;!-- store all my glyphs in a key --&gt;
  &lt;xsl:key name="glyphs" match="tei:glyph" use="@xml:id"/&gt;
  
  &lt;!-- handle glyphs, storing every step in a variable for debugging purposes --&gt;
  &lt;xsl:template match="tei:g"&gt;
     &lt;xsl:variable name="g_name" select="substring(@ref,2)"/&gt;
     &lt;xsl:variable name="glyph" select="key('glyphs', $g_name)"/&gt;
     &lt;xsl:variable name="mapping" select="$glyph/tei:mapping[@type='norm']"/&gt;
     &lt;xsl:value-of select="$mapping"/&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p>This would, as expected, output "sem".</p>
  
  <p>But, if I want to write a stylesheet that displays the text diplomatically, I'd want the output to be "ſem".<br>
  For that, I started with:</p>
  
  <pre><code>&lt;xsl:template match="tei:g"&gt;
     &lt;xsl:variable name="g_name" select="substring(@ref,2)"/&gt;
     &lt;xsl:variable name="glyph" select="key('glyphs', $g_name)"/&gt;
     &lt;xsl:variable name="mapping" select="$glyph/tei:mapping[@type='facs']"/&gt;
     &lt;xsl:value-of select="$mapping"/&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p>That gave me "U+017Fem". Of course, that's not a HTML entity for the expected special character.</p>
  
  <p>So I tried:</p>
  
  <pre><code>&lt;xsl:template match="tei:g"&gt;
     &lt;xsl:variable name="g_name" select="substring(@ref,2)"/&gt;
     &lt;xsl:variable name="glyph" select="key('glyphs', $g_name)"/&gt;
     &lt;xsl:variable name="mapping" select="$glyph/tei:mapping[@type='facs']"/&gt;
     &lt;xsl:variable name="entity" select="concat('&amp;amp;#x',substring($mapping,3),';')"/&gt;
     &lt;xsl:value-of select="$entity"/&gt;
  &lt;/xsl:template&gt;
  </code></pre>
  
  <p>That outputs <code>&amp;#x017F;em</code>, which looks a lot more like a HTML hex entity. But sadly, it still gets displayed as such, and not interpreted as the character represented by the entity.</p>
  
  <p>And I can't for the life of me figure out, how I get it to do that.  </p>
  
  <p>PS: If that helps, I'm not writing a stylesheet to create a HTML file that I open in the browser afterwards; I have a HTML file with a JavaScript function, that converts the XML data to HTML "on the fly".</p>
  
  <p><strong>Edit:</strong></p>
  
  <p>As pointed out by Martin Honnen, on non-Mozilla browsers, <code>&lt;xsl:value-of select="$entity" disable-output-escaping="yes"/&gt;</code> should suffice (see <a href="https://xsltfiddle.liberty-development.net/ejivdH4/2" rel="nofollow noreferrer">https://xsltfiddle.liberty-development.net/ejivdH4/2</a>).</p>
  
  <p>Yet, for me, that still doesn't work. So I'm guessing I'm missing something important. Here are my full files (file.xml is shortened/changed, because the original is work in prograss by others, buit the result is the same).</p>
  
  <p>file.xml:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?&gt;
  &lt;?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml"
      schematypens="http://purl.oclc.org/dsdl/schematron"?&gt;
  
  
  &lt;TEI xmlns="http://www.tei-c.org/ns/1.0"&gt;
     &lt;teiHeader&gt;
        &lt;fileDesc&gt;
           &lt;titleStmt&gt;
              &lt;title&gt;Title&lt;/title&gt;
           &lt;/titleStmt&gt;
           &lt;publicationStmt&gt;
              &lt;p&gt;Publication Information&lt;/p&gt;
           &lt;/publicationStmt&gt;
           &lt;sourceDesc&gt;
              &lt;p&gt;Information about the source&lt;/p&gt;
           &lt;/sourceDesc&gt;
        &lt;/fileDesc&gt;
        &lt;encodingDesc&gt;
           &lt;charDecl&gt;
              &lt;desc&gt;Variant letter forms&lt;/desc&gt;
              &lt;glyph xml:id="aalig"&gt;
                 &lt;glyphName&gt;LATIN SMALL LIGATURE AA&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+EFA0&lt;/mapping&gt;
                 &lt;mapping type="norm"&gt;aa&lt;/mapping&gt;
              &lt;/glyph&gt;           
              &lt;glyph xml:id="fins"&gt;
                 &lt;glyphName&gt;LATIN SMALL LETTER INSULAR F&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+F207&lt;/mapping&gt;
                 &lt;mapping type="norm"&gt;f&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="jscap"&gt;
                 &lt;glyphName&gt;LATIN LETTER SMALL CAPITAL J&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+1DOA&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="nscap"&gt;
                 &lt;glyphName&gt;LATIN LETTER SMALL CAPITAL N&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+0274&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="rrot"&gt;
                 &lt;glyphName&gt;LATIN SMALL LETTER R ROTUNDA&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+A75B&lt;/mapping&gt;
                 &lt;mapping type="norm"&gt;r&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="rscap"&gt;
                 &lt;glyphName&gt;LATIN LETTER SMALL CAPITAL R&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+0280&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="slong"&gt;
                 &lt;glyphName&gt;LATIN SMALL LETTER LONG S&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+017F&lt;/mapping&gt;
                 &lt;mapping type="norm"&gt;s&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="sscap"&gt;
                 &lt;glyphName&gt;LATIN LETTER SMALL CAPITAL S&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+A731&lt;/mapping&gt;
              &lt;/glyph&gt;
           &lt;/charDecl&gt;
           &lt;charDecl&gt;
              &lt;desc&gt;Abbreviation marks&lt;/desc&gt;
              &lt;glyph xml:id="ar"&gt;
                 &lt;glyphName&gt;LATIN ABBREVIATION SIGN&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+036C&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="asup"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER A&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+0363&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="bar"&gt;
                 &lt;glyphName&gt;COMBINING ABBREVIATION MARK BAR ABOVE&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+0305&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="combcurl"&gt;
                 &lt;glyphName&gt;COMBINING OGONEK ABOVE&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+1DCS&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="csup"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER C&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+0368&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="dot"&gt;
                 &lt;glyphName&gt;DOT ABOVE&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+02D9&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="dsup"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER D&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+0369&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="er"&gt;
                 &lt;glyphName&gt;COMBINING ABBREVIATION MARK ZIGZAG ABOVE&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+035B&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="et"&gt;
                 &lt;glyphName&gt;LATIN ABBREVIATION SIGN SMALL ET WITH STROKE&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+F158&lt;/mapping&gt;
                 &lt;mapping type="norm"&gt;&amp;amp;&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="ezh"&gt;
                 &lt;glyphName&gt;LATIN SMALL LETTER EZH&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+0292&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="isup"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER I&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+0365&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="nsup"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER N&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+F021&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="osup"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER O&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+0366&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="ra"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+F1C1&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="rsup"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER R&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+036C&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="tsup"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER T&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+036D&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="ur"&gt;
                 &lt;glyphName&gt;COMBINING ABBREVIATION MARK SUPERSCRIPT UR ROUND R FORM&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+F153&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="us"&gt;
                 &lt;glyphName&gt;COMBINING US ABOVE&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+1DD2&lt;/mapping&gt;
              &lt;/glyph&gt;
              &lt;glyph xml:id="zsup"&gt;
                 &lt;glyphName&gt;COMBINING LATIN SMALL LETTER Z&lt;/glyphName&gt;
                 &lt;mapping type="facs"&gt;U+00B3&lt;/mapping&gt;
              &lt;/glyph&gt;
           &lt;/charDecl&gt;
        &lt;/encodingDesc&gt;
  
     &lt;/teiHeader&gt;
     &lt;text&gt;
        &lt;body&gt; 
  
           &lt;!-- Add your data between here ... --&gt;
  
  
           &lt;div type="miracle" n="75"&gt;
  
              &lt;pb n="473"/&gt;
  
  
              &lt;head&gt; &lt;lb n="2"/&gt;Bla&lt;/head&gt;
  
              &lt;p&gt;
                 &lt;g ref="#slong"/&gt;em 
              &lt;/p&gt;
  
           &lt;/div&gt;
        &lt;/body&gt;
     &lt;/text&gt;
  &lt;/TEI&gt;
  </code></pre>
  
  <p>page.html</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;!DOCTYPE html&gt;
  &lt;html&gt;
      &lt;head&gt;
        &lt;meta charset="utf-8"/&gt;
          &lt;script&gt;
  function loadXMLDoc(filename)
  {
  if (window.ActiveXObject)
    {
    xhttp = new ActiveXObject("Msxml2.XMLHTTP");
    }
  else
    {
    xhttp = new XMLHttpRequest();
    }
  xhttp.open("GET", filename, false);
  try {xhttp.responseType = "msxml-document"} catch(err) {} // Helping IE11
  xhttp.send(""); 
  return xhttp.responseXML;
  } 
  
  function displayResult(style)
  {
  console.log('Generating...');
  xml = loadXMLDoc("file.xml");
  xsl = loadXMLDoc(style);
  // code for IE
  if (window.ActiveXObject || xhttp.responseType == "msxml-document")
    {
    ex = xml.transformNode(xsl);
    document.getElementById("example").innerHTML = ex;
    }
  // code for Chrome, Firefox, Opera, etc.
  else if (document.implementation &amp;&amp; document.implementation.createDocument)
    {
    xsltProcessor = new XSLTProcessor();
    xsltProcessor.importStylesheet(xsl);
    resultDocument = xsltProcessor.transformToFragment(xml, document);
    const node = document.getElementById("example");
    while (node.firstChild){
      node.removeChild(node.firstChild);
     }
    node.appendChild(resultDocument);
    }
  }
  &lt;/script&gt;
      &lt;/head&gt; 
      &lt;body onload="displayResult('facs.xsl')"&gt;
        &lt;h1&gt;Test&lt;/h1&gt;
        &lt;div&gt;
          &lt;button onclick="displayResult('facs.xsl')"&gt;facs&lt;/button&gt;
          &lt;button onclick="displayResult('dipl.xsl')"&gt;dipl&lt;/button&gt;
        &lt;/div&gt;
          &lt;div id="example" /&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>facs.xsl</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0"&gt;
  
  
    &lt;xsl:key name="glyphs" match="tei:glyph" use="@xml:id"/&gt;
  
  
  &lt;xsl:template match="/"&gt;
    &lt;h3&gt;TEI Rendering: Facsimile&lt;/h3&gt;
    &lt;div&gt;
      &lt;xsl:apply-templates select="//tei:div[@type='miracle']"/&gt;
    &lt;/div&gt;
  &lt;/xsl:template&gt;
  
  
    &lt;xsl:template match="tei:div[@type='miracle']"&gt;
      &lt;h5&gt;
        Miracle: 
        &lt;xsl:value-of select="@n"/&gt;
      &lt;/h5&gt;
      &lt;div class="miracle"&gt;
        &lt;xsl:apply-templates/&gt;
      &lt;/div&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="tei:head"&gt;
      &lt;div style="color:red"&gt;
        &lt;xsl:apply-templates/&gt;
      &lt;/div&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="tei:pb"&gt;
      &lt;br/&gt;
      (&lt;xsl:value-of select="@n"/&gt;)
      &lt;br/&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="tei:lb"&gt;
      &lt;br/&gt;&lt;xsl:value-of select="@n"/&gt;: 
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="tei:am"&gt;
      &lt;xsl:apply-templates/&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="tei:g"&gt;
      &lt;xsl:variable name="g_name" select="substring(@ref,2)"/&gt;
      &lt;xsl:variable name="glyph" select="key('glyphs', $g_name)"/&gt;
      &lt;xsl:variable name="mapping" select="$glyph/tei:mapping[@type='facs']"/&gt;
      &lt;xsl:variable name="entity" select="concat('&amp;amp;#x',substring($mapping,3),';')"/&gt;
      &lt;xsl:value-of select="$entity" disable-output-escaping="yes"/&gt;
  
  
  
      &lt;xsl:variable name="something" select="'&amp;amp;#x0305;'"/&gt;
      {&lt;xsl:value-of select="$something" disable-output-escaping="yes"/&gt;}
    &lt;/xsl:template&gt;
  
  
  
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>dipl.xsl</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0"&gt;
  
  
  
  &lt;xsl:template match="/"&gt;
    &lt;h3&gt;TEI Rendering: Diplomatic&lt;/h3&gt;
    &lt;div&gt;
      &lt;xsl:apply-templates select="//tei:div[@type='miracle']"/&gt;
    &lt;/div&gt;
  &lt;/xsl:template&gt;
  
  
    &lt;xsl:template match="tei:div[@type='miracle']"&gt;
      &lt;h5&gt;
        Miracle: 
        &lt;xsl:value-of select="@n"/&gt;
      &lt;/h5&gt;
      &lt;div class="miracle"&gt;
        &lt;xsl:apply-templates/&gt;
      &lt;/div&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="tei:head"&gt;
      &lt;div style="color:red"&gt;
        &lt;xsl:apply-templates/&gt;
      &lt;/div&gt;
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="tei:pb"&gt;
       || 
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="tei:lb"&gt;
      |
    &lt;/xsl:template&gt;
  
    &lt;xsl:template match="tei:ex"&gt;
      &lt;i&gt;
        &lt;xsl:apply-templates/&gt;
      &lt;/i&gt;
    &lt;/xsl:template&gt;
  
  
  
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>I'm viewing the file as localhost (with a python server running) in my browser.</p>
  
  <p>Any thoughts, what I might be missing or doing wrong?</p>
  
  <p>Note: A lookup-table is not what I want, bevause potentially, there might be as many special characters in a TEI-XML, as there are unicode characters. That's what the glyphe-mappings are here for.</p>
  
  <p>XSLT 2.0 might be an option; but I haven't figured out how to do a 2.0 transformation in the browser via JavaScript.</p>
  
  <p><strong>Edit 2:</strong></p>
  
  <p>I don't know what had gone wrong when I tested it first, but on IE it works with <code>&lt;xsl:value-of select="$entity" disable-output-escaping="yes"/&gt;</code>.<br>
  But since it doesn't work with Firefox, I decided to change the whole design: I transform the XML on server side with PHP and send the HTML to the client; that should work with every browser. </p>