Я экспериментирую с написанием таблицы стилей 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('&#x',substring($mapping,3),';')"/>
<xsl:value-of select="$entity"/>
</xsl:template>
Это выдает ſ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">&</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('&#x',substring($mapping,3),';')"/>
<xsl:value-of select="$entity" disable-output-escaping="yes"/>
<xsl:variable name="something" select="'&#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клиент;это должно работать с каждым браузером.