0

我正在尝试编写一个 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('&amp;#x',substring($mapping,3),';')"/>
   <xsl:value-of select="$entity"/>
</xsl:template>

输出&#x017F;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">&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 可能是一个选项;但我还没有弄清楚如何通过 JavaScript 在浏览器中进行 2.0 转换。

编辑2:

我不知道我第一次测试时出了什么问题,但在 IE 上它可以与<xsl:value-of select="$entity" disable-output-escaping="yes"/>.
但由于它不适用于 Firefox,我决定改变整个设计:我在服务器端使用 PHP 转换 XML,然后将 HTML 发送到客户端;这应该适用于每个浏览器。

4

1 回答 1

0

如果您以 Chrome 或 Edge 或 IE 为目标,那么我认为使用<xsl:value-of select="$entity" disable-output-escaping="yes"/>就足够了,在https://xsltfiddle.liberty-development.net/ejivdH4/2中可用于输出ſem前两个浏览器和 IE 的十六进制字符引用&#x017F;em与转换使用 Javascript API 在浏览器中完成。

众所周知,Mozilla 浏览器不支持disable-output-escaping,因此对于跨浏览器、客户端 XSLT 1,michael.hor257k 的“构建您自己的查找表”的建议可能是更好的选择。

于 2019-10-20T09:36:36.460 回答