Как создать шестнадцатеричный объект HTML с помощью XSLT - PullRequest
0 голосов
/ 20 октября 2019

Я экспериментирую с написанием таблицы стилей XSLT для генерации HTML из текста, закодированного в XML в соответствии со стандартом TEI.

Теперь, когда речь идет о специальных символах, я сталкиваюсь с трудностями - вотпример: слово "ſem" (нормализованное "sem", старое норвежское относительное местоимение) будет закодировано <g ref="#slong"/>em, что означает следующее объявление в заголовке:

<glyph xml:id="slong">
   <glyphName>LATIN SMALL LETTER LONG S</glyphName>
   <mapping type="facs">U+017F</mapping>
   <mapping type="norm">s</mapping>
</glyph>

Конечно, идеябыть, чтобы иметь возможность искать сопоставления для каждого глифа, а затем отображать его соответствующим образом.
Например, если бы я хотел иметь таблицу стилей, которая показывает нормализованный рендеринг текста, у меня было бы что-то вроде

<!-- store all my glyphs in a key -->
<xsl:key name="glyphs" match="tei:glyph" use="@xml:id"/>

<!-- handle glyphs, storing every step in a variable for debugging purposes -->
<xsl:template match="tei:g">
   <xsl:variable name="g_name" select="substring(@ref,2)"/>
   <xsl:variable name="glyph" select="key('glyphs', $g_name)"/>
   <xsl:variable name="mapping" select="$glyph/tei:mapping[@type='norm']"/>
   <xsl:value-of select="$mapping"/>
</xsl:template>

Это, как и ожидалось, вывело бы "sem".

Но, если я хочу написать таблицу стилей, которая отображает текст дипломатически, я бы хотел, чтобы вывод был ""em".
Для этого я начал с:

<xsl:template match="tei:g">
   <xsl:variable name="g_name" select="substring(@ref,2)"/>
   <xsl:variable name="glyph" select="key('glyphs', $g_name)"/>
   <xsl:variable name="mapping" select="$glyph/tei:mapping[@type='facs']"/>
   <xsl:value-of select="$mapping"/>
</xsl:template>

Это дало мне "U + 017Fem". Конечно, это не HTML-сущность для ожидаемого специального символа.

Итак, я попытался:

<xsl:template match="tei:g">
   <xsl:variable name="g_name" select="substring(@ref,2)"/>
   <xsl:variable name="glyph" select="key('glyphs', $g_name)"/>
   <xsl:variable name="mapping" select="$glyph/tei:mapping[@type='facs']"/>
   <xsl:variable name="entity" select="concat('&amp;#x',substring($mapping,3),';')"/>
   <xsl:value-of select="$entity"/>
</xsl:template>

Это выдает &#x017F;em, который выглядит намного больше как шестнадцатеричная сущность HTML. Но, к сожалению, он все равно отображается как таковой и не интерпретируется как персонаж, представленный сущностью.

И я не могу понять, как мне это удается.

PS: Если это поможет, я не пишу таблицу стилей для создания HTML-файла, который впоследствии открываю в браузере;У меня есть HTML-файл с функцией JavaScript, который преобразует данные XML в HTML «на лету».

Редактировать:

Как указал Мартин Хоннен,в браузерах, не поддерживающих Mozilla, <xsl:value-of select="$entity" disable-output-escaping="yes"/> должно быть достаточно (см. https://xsltfiddle.liberty -development.net / ejivdH4 / 2 ).

Тем не менее, для меня это все еще не работает. Я предполагаю, что упускаю что-то важное. Вот мои полные файлы (файл file.xml укорочен / изменен, потому что оригинал работает в программном режиме другими, но результат тот же).

file.xml:

<?xml version="1.0" encoding="UTF-8"?>
<?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"?>
<?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"?>


<TEI xmlns="http://www.tei-c.org/ns/1.0">
   <teiHeader>
      <fileDesc>
         <titleStmt>
            <title>Title</title>
         </titleStmt>
         <publicationStmt>
            <p>Publication Information</p>
         </publicationStmt>
         <sourceDesc>
            <p>Information about the source</p>
         </sourceDesc>
      </fileDesc>
      <encodingDesc>
         <charDecl>
            <desc>Variant letter forms</desc>
            <glyph xml:id="aalig">
               <glyphName>LATIN SMALL LIGATURE AA</glyphName>
               <mapping type="facs">U+EFA0</mapping>
               <mapping type="norm">aa</mapping>
            </glyph>           
            <glyph xml:id="fins">
               <glyphName>LATIN SMALL LETTER INSULAR F</glyphName>
               <mapping type="facs">U+F207</mapping>
               <mapping type="norm">f</mapping>
            </glyph>
            <glyph xml:id="jscap">
               <glyphName>LATIN LETTER SMALL CAPITAL J</glyphName>
               <mapping type="facs">U+1DOA</mapping>
            </glyph>
            <glyph xml:id="nscap">
               <glyphName>LATIN LETTER SMALL CAPITAL N</glyphName>
               <mapping type="facs">U+0274</mapping>
            </glyph>
            <glyph xml:id="rrot">
               <glyphName>LATIN SMALL LETTER R ROTUNDA</glyphName>
               <mapping type="facs">U+A75B</mapping>
               <mapping type="norm">r</mapping>
            </glyph>
            <glyph xml:id="rscap">
               <glyphName>LATIN LETTER SMALL CAPITAL R</glyphName>
               <mapping type="facs">U+0280</mapping>
            </glyph>
            <glyph xml:id="slong">
               <glyphName>LATIN SMALL LETTER LONG S</glyphName>
               <mapping type="facs">U+017F</mapping>
               <mapping type="norm">s</mapping>
            </glyph>
            <glyph xml:id="sscap">
               <glyphName>LATIN LETTER SMALL CAPITAL S</glyphName>
               <mapping type="facs">U+A731</mapping>
            </glyph>
         </charDecl>
         <charDecl>
            <desc>Abbreviation marks</desc>
            <glyph xml:id="ar">
               <glyphName>LATIN ABBREVIATION SIGN</glyphName>
               <mapping type="facs">U+036C</mapping>
            </glyph>
            <glyph xml:id="asup">
               <glyphName>COMBINING LATIN SMALL LETTER A</glyphName>
               <mapping type="facs">U+0363</mapping>
            </glyph>
            <glyph xml:id="bar">
               <glyphName>COMBINING ABBREVIATION MARK BAR ABOVE</glyphName>
               <mapping type="facs">U+0305</mapping>
            </glyph>
            <glyph xml:id="combcurl">
               <glyphName>COMBINING OGONEK ABOVE</glyphName>
               <mapping type="facs">U+1DCS</mapping>
            </glyph>
            <glyph xml:id="csup">
               <glyphName>COMBINING LATIN SMALL LETTER C</glyphName>
               <mapping type="facs">U+0368</mapping>
            </glyph>
            <glyph xml:id="dot">
               <glyphName>DOT ABOVE</glyphName>
               <mapping type="facs">U+02D9</mapping>
            </glyph>
            <glyph xml:id="dsup">
               <glyphName>COMBINING LATIN SMALL LETTER D</glyphName>
               <mapping type="facs">U+0369</mapping>
            </glyph>
            <glyph xml:id="er">
               <glyphName>COMBINING ABBREVIATION MARK ZIGZAG ABOVE</glyphName>
               <mapping type="facs">U+035B</mapping>
            </glyph>
            <glyph xml:id="et">
               <glyphName>LATIN ABBREVIATION SIGN SMALL ET WITH STROKE</glyphName>
               <mapping type="facs">U+F158</mapping>
               <mapping type="norm">&amp;</mapping>
            </glyph>
            <glyph xml:id="ezh">
               <glyphName>LATIN SMALL LETTER EZH</glyphName>
               <mapping type="facs">U+0292</mapping>
            </glyph>
            <glyph xml:id="isup">
               <glyphName>COMBINING LATIN SMALL LETTER I</glyphName>
               <mapping type="facs">U+0365</mapping>
            </glyph>
            <glyph xml:id="nsup">
               <glyphName>COMBINING LATIN SMALL LETTER N</glyphName>
               <mapping type="facs">U+F021</mapping>
            </glyph>
            <glyph xml:id="osup">
               <glyphName>COMBINING LATIN SMALL LETTER O</glyphName>
               <mapping type="facs">U+0366</mapping>
            </glyph>
            <glyph xml:id="ra">
               <glyphName>COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE</glyphName>
               <mapping type="facs">U+F1C1</mapping>
            </glyph>
            <glyph xml:id="rsup">
               <glyphName>COMBINING LATIN SMALL LETTER R</glyphName>
               <mapping type="facs">U+036C</mapping>
            </glyph>
            <glyph xml:id="tsup">
               <glyphName>COMBINING LATIN SMALL LETTER T</glyphName>
               <mapping type="facs">U+036D</mapping>
            </glyph>
            <glyph xml:id="ur">
               <glyphName>COMBINING ABBREVIATION MARK SUPERSCRIPT UR ROUND R FORM</glyphName>
               <mapping type="facs">U+F153</mapping>
            </glyph>
            <glyph xml:id="us">
               <glyphName>COMBINING US ABOVE</glyphName>
               <mapping type="facs">U+1DD2</mapping>
            </glyph>
            <glyph xml:id="zsup">
               <glyphName>COMBINING LATIN SMALL LETTER Z</glyphName>
               <mapping type="facs">U+00B3</mapping>
            </glyph>
         </charDecl>
      </encodingDesc>

   </teiHeader>
   <text>
      <body> 

         <!-- Add your data between here ... -->


         <div type="miracle" n="75">

            <pb n="473"/>


            <head> <lb n="2"/>Bla</head>

            <p>
               <g ref="#slong"/>em 
            </p>

         </div>
      </body>
   </text>
</TEI>

page.html

<!DOCTYPE html>
<html>
    <head>
      <meta charset="utf-8"/>
        <script>
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 && 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);
  }
}
</script>
    </head> 
    <body onload="displayResult('facs.xsl')">
      <h1>Test</h1>
      <div>
        <button onclick="displayResult('facs.xsl')">facs</button>
        <button onclick="displayResult('dipl.xsl')">dipl</button>
      </div>
        <div id="example" />
    </body>
</html>

facs.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0">


  <xsl:key name="glyphs" match="tei:glyph" use="@xml:id"/>


<xsl:template match="/">
  <h3>TEI Rendering: Facsimile</h3>
  <div>
    <xsl:apply-templates select="//tei:div[@type='miracle']"/>
  </div>
</xsl:template>


  <xsl:template match="tei:div[@type='miracle']">
    <h5>
      Miracle: 
      <xsl:value-of select="@n"/>
    </h5>
    <div class="miracle">
      <xsl:apply-templates/>
    </div>
  </xsl:template>

  <xsl:template match="tei:head">
    <div style="color:red">
      <xsl:apply-templates/>
    </div>
  </xsl:template>

  <xsl:template match="tei:pb">
    <br/>
    (<xsl:value-of select="@n"/>)
    <br/>
  </xsl:template>

  <xsl:template match="tei:lb">
    <br/><xsl:value-of select="@n"/>: 
  </xsl:template>

  <xsl:template match="tei:am">
    <xsl:apply-templates/>
  </xsl:template>

  <xsl:template match="tei:g">
    <xsl:variable name="g_name" select="substring(@ref,2)"/>
    <xsl:variable name="glyph" select="key('glyphs', $g_name)"/>
    <xsl:variable name="mapping" select="$glyph/tei:mapping[@type='facs']"/>
    <xsl:variable name="entity" select="concat('&amp;#x',substring($mapping,3),';')"/>
    <xsl:value-of select="$entity" disable-output-escaping="yes"/>



    <xsl:variable name="something" select="'&amp;#x0305;'"/>
    {<xsl:value-of select="$something" disable-output-escaping="yes"/>}
  </xsl:template>



</xsl:stylesheet>

dipl.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0">



<xsl:template match="/">
  <h3>TEI Rendering: Diplomatic</h3>
  <div>
    <xsl:apply-templates select="//tei:div[@type='miracle']"/>
  </div>
</xsl:template>


  <xsl:template match="tei:div[@type='miracle']">
    <h5>
      Miracle: 
      <xsl:value-of select="@n"/>
    </h5>
    <div class="miracle">
      <xsl:apply-templates/>
    </div>
  </xsl:template>

  <xsl:template match="tei:head">
    <div style="color:red">
      <xsl:apply-templates/>
    </div>
  </xsl:template>

  <xsl:template match="tei:pb">
     || 
  </xsl:template>

  <xsl:template match="tei:lb">
    |
  </xsl:template>

  <xsl:template match="tei:ex">
    <i>
      <xsl:apply-templates/>
    </i>
  </xsl:template>



</xsl:stylesheet>

Я просматриваю файл как localhost (на сервере pythonв моем браузере.

Есть мысли, что я могу упустить или сделать неправильно?

Примечание: таблица поиска - это не то, что я хочу, потому что потенциально, их может быть столько жеспециальные символы в TEI-XML, так как есть символы Unicode. Вот для чего здесь глиф-отображения.

XSLT 2.0 может быть вариантом;но я не понял, как выполнить преобразование 2.0 в браузере с помощью JavaScript.

Редактировать 2:

Я не знаю, что пошло не так, когдаСначала я протестировал его, но в IE он работает с <xsl:value-of select="$entity" disable-output-escaping="yes"/>.
Но поскольку он не работает с Firefox, я решил изменить весь дизайн: я преобразовываю XML на стороне сервера с помощью PHP и отправляю HTMLклиент;это должно работать с каждым браузером.

1 Ответ

0 голосов
/ 20 октября 2019

Если вы нацелены на Chrome, Edge или IE, то, я думаю, будет достаточно использовать <xsl:value-of select="$entity" disable-output-escaping="yes"/>, в https://xsltfiddle.liberty -development.net / ejivdH4 / 2 , который работает для вывода ſem для первых двухбраузеры и шестнадцатеричная ссылка на символ &#x017F;em для IE с преобразованием, выполненным в браузере с использованием Javascript API.

Известно, что браузеры Mozilla не поддерживают disable-output-escaping, поэтому для кросс-браузерного XSLT на стороне клиента1 предложение «построить свою собственную справочную таблицу» от michael.hor257k, вероятно, является лучшим вариантом.

...