我正在尝试编写一个 XSLT 样式表,以根据 TEI 标准从以 XML 编码的文本生成 HTML。
现在,当涉及到特殊字符时,我遇到了困难——这里有一个例子:单词“ſ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 文件;我有一个带有 JavaScript 函数的 HTML 文件,它可以“即时”将 XML 数据转换为 HTML。
编辑:
正如 Martin Honnen 所指出的,在非 Mozilla 浏览器上<xsl:value-of select="$entity" disable-output-escaping="yes"/>
应该就足够了(参见https://xsltfiddle.liberty-development.net/ejivdH4/2)。
然而,对我来说,这仍然行不通。所以我猜我错过了一些重要的东西。这是我的完整文件(file.xml 被缩短/更改,因为原始文件是其他人在进行中的工作,但结果是一样的)。
文件.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 可能是一个选项;但我还没有弄清楚如何通过 JavaScript 在浏览器中进行 2.0 转换。
编辑2:
我不知道我第一次测试时出了什么问题,但在 IE 上它可以与<xsl:value-of select="$entity" disable-output-escaping="yes"/>
.
但由于它不适用于 Firefox,我决定改变整个设计:我在服务器端使用 PHP 转换 XML,然后将 HTML 发送到客户端;这应该适用于每个浏览器。