xsl

http://www.blogjava.net/rickhunter/articles/59742.html
http://www.blueidea.com/tech/web/2004/1798_4.asp

 本期介绍多个XSL对于VBScript、JScript增加的方法、属性,以充分发挥XML的优势,用于<xsl:script>、<xsl:eval>标记内表达式的编写或<xsl:if>、<xsl:when>的expr属性。

  一、absoluteChildNumber

  含义:返回结点相对于它所有的兄弟(不论名字是否相同)的序号。

  语法:absoluteChildNumber(node)

  参数:node ── 对象,欲返回编号的结点。

  示例:

  1、假定文档结构为:<document><head/><body/></document>,其中document为顶层结点,下述表达式将输出:

<xsl:eval>
absoluteChildNumber(this.selectNodes('/document/body').item(0))
</xsl:eval>

  2、确定当前结点相对于其所有兄弟的序号:

<xsl:eval>
absoluteChildNumber(this)
</xsl:eval>

  二、ancestorChildNumber

  含义:从给定结点出发根据给定祖先结点名返回最近的祖先结点的序号(相对于同名结点)。如果找不祖先,则返回0。

  语法:ancestorChildNumber(bstrNodeName, pNode)

  参数:

  bstrNodeName ── 字符串。被搜索的祖先结点的名字。

  pNode ── 对象。搜索开始位置的结点。

  示例查找当前结点最近的名为report祖先结点:

ancestorChildNumber('report',this)

  三、attributes

  含义:返回结点属性的集合。

  语法:object.attributes

  参数:object ── 结点对象。

  示例:当前结点属性的个数

this.attributes.length

  当前结点第三个属性的值

this.attributs.item(2).value



this.attributes.item(2).text



this.attributes(2).text

  注意:如果给定的下标大于属性总和减1将出错,第一个属性的下标是0。

  四、baseName

  含义:返回有名字空间限制的基本名,即不包括名字前缀。

  语法:object.baseName

  参数:object ── 结点对象

  示例,当前结点的基本名:

this.baseName

  五、childNumber

  含义:返回结点相对于同名同胞的序号。

  语法:childNumber(object)

  参数:object ── 结点对象

  示例,假定XML文档结构如下:

<x><y><z></z></y></x>

  如果当前结点是z,则childNumber(this)返回1,而absoluteChildNumber(this)返回3。

  六、dataType

  含义:设定或读取结点的数据类型。

  语法:设定结点的数据类型 object.dataType=objValue
     读取结点的数据类型 objValue=object.dataType

  参数:object ── 结点对象。

  示例,读取当前结点的数据类型:

dtType=this.dataType

  七、depth

  含义:指定结点出现在文档树上的深度,即该结点位于文档第几层,顶层结点位于第一层,根结点(即用"/"表示的结点)位于第0层。

  语法:depth(pNode)

  参数:pNode ── 结点对象

  示例,当前结点的深度:

depth(this)

  八、firstChild、lastChild

  含义:返回结点的第一个子结点(或最后一个子结点)。

  语法:pNode.firstChild
     pNode.lastChild

  参数:pNode ── 结点对象

  示例,当前结点的第一个结点的名字:

this.firstChild.nodeName

  九、formatIndex

  含义:用指定的计数系统格式化提供的整数。

  语法:formatIndex(lIndex, bstrFormat)

  参数:

  lIndex ── 整型数值或变量

  bstrFormat ── 数据格式,可选值有a、A、i、I、1、01(以0打头的数值形式,如果要求固定长度的编号如0001、0002则非常有用)。

  示例,当前结点的大写罗马数字编号:

formatIndex(childNumber(this),'I')

  十、formatNumber

  含义:以指定格式输出数值。

  语法:formatNumber(dblNumber, bstrFormat)

  参数:说明同formatNumber,不同之处在于格式化的可以是小数。

  示例,对变量a的值格式化为两位小数:

formatNumber(a,'#.00'):

  十一、hasChildNodes

  含义:如果结点有子结点则返回true(-1),否则为false(0)。

  语法:pNode.hasChildNodes()

  注意:与此前介绍的函数不同,此函数后必须带一个空括号。

  示例,判断当前结点是否有子结点:

this.hasChildNodes

  十二、namespaceURI、prefix

  含义:返回结点名字空间的全局资源标识符(或前缀)。

  语法:pNode.namespaceURI
     pNode.prifix

  十三、nextSibling、previousSibling、parentNode

  含义:返回结点的下一个兄弟(或前一个兄弟、或结点的父结点)。

  语法:pNode.nextSibling
     pNode.previousSibling
     pNode.parentNode

  注意:对根结点(即"/")应用parentNode方法、对第一个孩子结点应用previousSibling方法、对最后一个孩子结点应用nextSibling方法均会导致错误,可通过此过关系运算符==(等于)和!=(不等于)来判断一个结点是否某一指定结点,格式为pNode1 = pNode2或pNode2 != pNode2。

  十四、nodeName

  含义:返回元素、属性、入口的名字或其他类型结点的一个特定字符串。

  语法:pNode.nodeName

  示例,当前结点的名字:

this.nodeName

  十五、nodeType、NodeTypeString

  含义:返回结点的类型的数值形式(或字符串形式)。

  语法:pNode.nodeType 或 pNode.nodeTypeString

  返回值:

 结点类型 结点类型值 结点的字符形式描述
 Element 1 'element'
 Element Attribute 2 'attribute'
 Markup-Delimited Region of Text 3 'text'
 Processing Instruction 7 'processing_instruction'
 Comment 8 'comment'
 Document Entity 9 'document'

  十六、nodeTypedValue

  含义:以结点预定义的数据类型返回结点的值。

  语法:pNode.nodeTypedValue

  示例,假定当前结点的数据类型是fixed.14.4,下例将以数值返回结点的值,而不是文本一个字符串:

this.nodeTypedValue

  十七、nodeValue

  含义:返回结点的文本。

  语法:pNode.nodeValue

  注意:该方法不用于元素类结点,可用于属性、CDATA、注释、文本等结点。

  示例,当前元素第一个属性的值:

this.attributes(0).nodeValue

  当前元素内的文本(假定该元素内只有文本,无其它元素,即<mark>text</mark>,建议多尝几次掌握其确切的用法)。

this.firstChild.nodeValue

  十八、ownerDocument

  含义:返回包含该结点的文档的根。

  语法:pNode.ownerDocument

  注意:该方法用于文档的根结点将出错。

  十九、selectNodes

  含义:给定的样式匹配应用于当前结点并返回匹配的结点集合。

  语法:pNode.selectNodes('pattern')

  提示:pattern的编写与<xsl:for-each>的select属性的值类似,其中以"/"开头表示从文档的根出发搜索;以"//"开头表遍历文档的所有结点;以".."开头表示从当前结点的父结点开始;如果欲从当前结点向下搜索则不能有以上特殊字符打头。

  示例,与当前结点同名的元素在其父元素内的个数:

childNumber(this.selectNodes("../"+this.nodeName+"[end()]").item(0))

  当前元素内名字为"skill"的元素的个数:

childNumber(this.selectNodes("skill[end()]").item(0))

  二十、selectSingleNode

  含义:与selectNodes类似,不同的只返回匹配的第一个结点、而不是结点集合。

  语法:pNode.selectSingleNode('pattern')

  示例,与当前结点同名的元素在其父元素内的个数:

childNumber(this.selectSingleNode("../"+this.nodeName+"[end()]"))

  当前元素内名字为"skill"的元素的个数:

childNumber(this.selectSingleNode("skill[end()]"))

  二十一、text

  含义:返回结点与它的子树内的文字内容。

  语法:pNode.text

  示例,整个文档内的文字内容:

this.ownerDocument.text

  当前元素及其子树的文字内容:

this.text

  二十二、xml

  含义:返回结点及其后代的XML表示。

  语法:pNode.xml

  示例,当前文档的XML内容:

this.ownerDocument.xml

  另有几个函数不作介绍,列于其下以供参考,如感兴趣,请访问http://msdn.microsoft.com获取详细说明。

formatTime(varTime, bstrFormat,varDestLocale)
formatDate(varDate, bstrFormat,varDestLocale)
apendChild(newChild)
definition
CloneNode
insertBefore(newChild, refChild)
parsed
removeChild(oldChild)
replaceChild(newChild, oldChild)
specified
transformNode(stylesheet)
transformNodeToObject(stylesheet,outputObject)
uniqueID(pNode)

60862.html

船长 2006-07-30 14:57 发表评论
这个也是公式的xsl<?xml version='1.0' encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://www.w3.org/1998/Math/MathML" version='1.0'> <!-- ====================================================================== --> <!-- $Id: tokens.xsl,v 1.7 2003/06/10 12:24:05 shade33 Exp $ This file is part of the XSLT MathML Library distribution. See ./README or http://www.raleigh.ru/MathML/mmltex for copyright and other information --> <!-- ====================================================================== --> <xsl:template match="m:mi|m:mn|m:mo|m:mtext|m:ms"> <xsl:call-template name="CommonTokenAtr"/> </xsl:template> <!-- 3.2.9 mglyph --> <xsl:template match="m:mglyph"> <xsl:text>\textcolor{red}{</xsl:text> <xsl:value-of select="@alt"/> <xsl:text>}</xsl:text> </xsl:template> <xsl:template name="mi"> <xsl:choose> <xsl:when test="string-length(normalize-space(.))>1 and not(@mathvariant)"> <xsl:text>\mathrm{</xsl:text> <xsl:apply-templates/> <xsl:text>}</xsl:text> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="mn"> <xsl:choose> <xsl:when test="string(number(.))='NaN' and not(@mathvariant)"> <xsl:text>\mathrm{</xsl:text> <xsl:apply-templates/> <xsl:text>}</xsl:text> </xsl:when> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- 3.2.5 Math Operator --> <xsl:template name="mo"> <xsl:if test="translate(normalize-space(.),'()[]}|','{{{{{{')='{'"> <xsl:choose> <xsl:when test="not(@stretchy='false') and count(preceding-sibling::m:mo[translate(normalize-space(.),'()[]}|','{{{{{{')='{'])mod 2=0 and following-sibling::m:mo[1][not(@stretchy='false')][translate(normalize-space(.),'()[]}|','{{{{{{')='{']"> <xsl:text>\left</xsl:text> </xsl:when> <xsl:when test="not(@stretchy='false') and count(preceding-sibling::m:mo[translate(normalize-space(.),'()[]}|','{{{{{{')='{'])mod 2=1 and preceding-sibling::m:mo[1][not(@stretchy='false')][translate(normalize-space(.),'()[]}|','{{{{{{')='{']"> <xsl:text>\right</xsl:text> </xsl:when> </xsl:choose> </xsl:if> <xsl:apply-templates/> </xsl:template> <xsl:template name="mtext"> <xsl:variable name="content"> <xsl:call-template name="replaceMtextEntities"> <xsl:with-param name="content" select="normalize-space(.)"/> </xsl:call-template> </xsl:variable> <xsl:text>\text{</xsl:text> <xsl:value-of select="$content"/> <xsl:text>}</xsl:text> </xsl:template> <xsl:template match="m:mspace"> <xsl:text>\phantom{\rule</xsl:text> <xsl:if test="@depth"> <xsl:text>[-</xsl:text> <xsl:value-of select="@depth"/> <xsl:text>]</xsl:text> </xsl:if> <xsl:text>{</xsl:text> <xsl:if test="not(@width)"> <xsl:text>0ex</xsl:text> </xsl:if> <xsl:value-of select="@width"/> <xsl:text>}{</xsl:text> <xsl:if test="not(@height)"> <xsl:text>0ex</xsl:text> </xsl:if> <xsl:value-of select="@height"/> <xsl:text>}}</xsl:text> </xsl:template> <xsl:template name="ms"> <xsl:choose> <xsl:when test="@lquote"><xsl:value-of select="@lquote"/></xsl:when> <xsl:otherwise><xsl:text>''</xsl:text></xsl:otherwise> </xsl:choose><xsl:apply-templates/><xsl:choose> <xsl:when test="@rquote"><xsl:value-of select="@rquote"/></xsl:when> <xsl:otherwise><xsl:text>''</xsl:text></xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="CommonTokenAtr"> <xsl:if test="@mathbackground"> <xsl:text>\colorbox[rgb]{</xsl:text> <xsl:call-template name="color"> <xsl:with-param name="color" select="@mathbackground"/> </xsl:call-template> <xsl:text>}{$</xsl:text> </xsl:if> <xsl:if test="@color[not(@mathcolor)] or @mathcolor"> <!-- Note: @color is deprecated in MathML 2.0 --> <xsl:text>\textcolor[rgb]{</xsl:text> <xsl:call-template name="color"> <xsl:with-param name="color" select="@color|@mathcolor"/> </xsl:call-template> <xsl:text>}{</xsl:text> </xsl:if> <xsl:if test="@mathvariant"> <xsl:choose> <xsl:when test="@mathvariant='normal'"> <xsl:text>\mathrm{</xsl:text> </xsl:when> <xsl:when test="@mathvariant='bold'"> <xsl:text>\mathbf{</xsl:text> </xsl:when> <xsl:when test="@mathvariant='italic'"> <xsl:text>\mathit{</xsl:text> </xsl:when> <xsl:when test="@mathvariant='bold-italic'"> <!-- not supported --> <xsl:text>\mathit{</xsl:text> <xsl:message>The value bold-italic for mathvariant is not supported</xsl:message> </xsl:when> <xsl:when test="@mathvariant='double-struck'"> <!-- Required amsfonts --> <xsl:text>\mathbb{</xsl:text> </xsl:when> <xsl:when test="@mathvariant='bold-fraktur'"> <!-- not supported --> <xsl:text>\mathfrak{</xsl:text> <xsl:message>The value bold-fraktur for mathvariant is not supported</xsl:message> </xsl:when> <xsl:when test="@mathvariant='script'"> <xsl:text>\mathcal{</xsl:text> </xsl:when> <xsl:when test="@mathvariant='bold-script'"> <!-- not supported --> <xsl:text>\mathcal{</xsl:text> <xsl:message>The value bold-script for mathvariant is not supported</xsl:message> </xsl:when> <xsl:when test="@mathvariant='fraktur'"> <!-- Required amsfonts --> <xsl:text>\mathfrak{</xsl:text> </xsl:when> <xsl:when test="@mathvariant='sans-serif'"> <xsl:text>\mathsf{</xsl:text> </xsl:when> <xsl:when test="@mathvariant='bold-sans-serif'"> <!-- not supported --> <xsl:text>\mathsf{</xsl:text> <xsl:message>The value bold-sans-serif for mathvariant is not supported</xsl:message> </xsl:when> <xsl:when test="@mathvariant='sans-serif-italic'"> <!-- not supported --> <xsl:text>\mathsf{</xsl:text> <xsl:message>The value sans-serif-italic for mathvariant is not supported</xsl:message> </xsl:when> <xsl:when test="@mathvariant='sans-serif-bold-italic'"> <!-- not supported --> <xsl:text>\mathsf{</xsl:text> <xsl:message>The value sans-serif-bold-italic for mathvariant is not supported</xsl:message> </xsl:when> <xsl:when test="@mathvariant='monospace'"> <xsl:text>\mathtt{</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>{</xsl:text> <xsl:message>Error at mathvariant attribute</xsl:message> </xsl:otherwise> </xsl:choose> </xsl:if> <xsl:call-template name="selectTemplate"/> <xsl:if test="@mathvariant"> <xsl:text>}</xsl:text> </xsl:if> <xsl:if test="@color or @mathcolor"> <xsl:text>}</xsl:text> </xsl:if> <xsl:if test="@mathbackground"> <xsl:text>$}</xsl:text> </xsl:if> </xsl:template> <xsl:template name="selectTemplate"> <xsl:choose> <xsl:when test="local-name(.)='mi'"> <xsl:call-template name="mi"/> </xsl:when> <xsl:when test="local-name(.)='mn'"> <xsl:call-template name="mn"/> </xsl:when> <xsl:when test="local-name(.)='mo'"> <xsl:call-template name="mo"/> </xsl:when> <xsl:when test="local-name(.)='mtext'"> <xsl:call-template name="mtext"/> </xsl:when> <xsl:when test="local-name(.)='ms'"> <xsl:call-template name="ms"/> </xsl:when> </xsl:choose> </xsl:template> <xsl:template name="color"> <!-- NB: Variables colora and valueColor{n} only for Sablotron --> <xsl:param name="color"/> <xsl:variable name="colora" select="translate($color,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')"/> <xsl:choose> <xsl:when test="starts-with($colora,'#') and string-length($colora)=4"> <xsl:variable name="valueColor"> <xsl:call-template name="Hex2Decimal"> <xsl:with-param name="arg" select="substring($colora,2,1)"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$valueColor div 15"/><xsl:text>,</xsl:text> <xsl:variable name="valueColor1"> <xsl:call-template name="Hex2Decimal"> <xsl:with-param name="arg" select="substring($colora,3,1)"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$valueColor1 div 15"/><xsl:text>,</xsl:text> <xsl:variable name="valueColor2"> <xsl:call-template name="Hex2Decimal"> <xsl:with-param name="arg" select="substring($colora,4,1)"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="$valueColor2 div 15"/> </xsl:when> <xsl:when test="starts-with($colora,'#') and string-length($colora)=7"> <xsl:variable name="valueColor1"> <xsl:call-template name="Hex2Decimal"> <xsl:with-param name="arg" select="substring($colora,2,1)"/> </xsl:call-template> </xsl:variable> <xsl:variable name="valueColor2"> <xsl:call-template name="Hex2Decimal"> <xsl:with-param name="arg" select="substring($colora,3,1)"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="($valueColor1*16 + $valueColor2) div 255"/><xsl:text>,</xsl:text> <xsl:variable name="valueColor1a"> <xsl:call-template name="Hex2Decimal"> <xsl:with-param name="arg" select="substring($colora,4,1)"/> </xsl:call-template> </xsl:variable> <xsl:variable name="valueColor2a"> <xsl:call-template name="Hex2Decimal"> <xsl:with-param name="arg" select="substring($colora,5,1)"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="($valueColor1a*16 + $valueColor2a) div 255"/><xsl:text>,</xsl:text> <xsl:variable name="valueColor1b"> <xsl:call-template name="Hex2Decimal"> <xsl:with-param name="arg" select="substring($colora,6,1)"/> </xsl:call-template> </xsl:variable> <xsl:variable name="valueColor2b"> <xsl:call-template name="Hex2Decimal"> <xsl:with-param name="arg" select="substring($colora,7,1)"/> </xsl:call-template> </xsl:variable> <xsl:value-of select="($valueColor1b*16 + $valueColor2b) div 255"/> </xsl:when> <!-- ======================= if color specifed as an html-color-name ========================================== --> <xsl:when test="$colora='aqua'"><xsl:text>0,1,1</xsl:text></xsl:when> <xsl:when test="$colora='black'"><xsl:text>0,0,0</xsl:text></xsl:when> <xsl:when test="$colora='blue'"><xsl:text>0,0,1</xsl:text></xsl:when> <xsl:when test="$colora='fuchsia'"><xsl:text>1,0,1</xsl:text></xsl:when> <xsl:when test="$colora='gray'"><xsl:text>.5,.5,.5</xsl:text></xsl:when> <xsl:when test="$colora='green'"><xsl:text>0,.5,0</xsl:text></xsl:when> <xsl:when test="$colora='lime'"><xsl:text>0,1,0</xsl:text></xsl:when> <xsl:when test="$colora='maroon'"><xsl:text>.5,0,0</xsl:text></xsl:when> <xsl:when test="$colora='navy'"><xsl:text>0,0,.5</xsl:text></xsl:when> <xsl:when test="$colora='olive'"><xsl:text>.5,.5,0</xsl:text></xsl:when> <xsl:when test="$colora='purple'"><xsl:text>.5,0,.5</xsl:text></xsl:when> <xsl:when test="$colora='red'"><xsl:text>1,0,0</xsl:text></xsl:when> <xsl:when test="$colora='silver'"><xsl:text>.75,.75,.75</xsl:text></xsl:when> <xsl:when test="$colora='teal'"><xsl:text>0,.5,.5</xsl:text></xsl:when> <xsl:when test="$colora='white'"><xsl:text>1,1,1</xsl:text></xsl:when> <xsl:when test="$colora='yellow'"><xsl:text>1,1,0</xsl:text></xsl:when> <xsl:otherwise> <xsl:message>Exception at color template</xsl:message> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template name="Hex2Decimal"> <xsl:param name="arg"/> <xsl:choose> <xsl:when test="$arg='f'"> <xsl:value-of select="15"/> </xsl:when> <xsl:when test="$arg='e'"> <xsl:value-of select="14"/> </xsl:when> <xsl:when test="$arg='d'"> <xsl:value-of select="13"/> </xsl:when> <xsl:when test="$arg='c'"> <xsl:value-of select="12"/> </xsl:when> <xsl:when test="$arg='b'"> <xsl:value-of select="11"/> </xsl:when> <xsl:when test="$arg='a'"> <xsl:value-of select="10"/> </xsl:when> <xsl:when test="translate($arg, '0123456789', '9999999999')='9'"> <!-- if $arg is number --> <xsl:value-of select="$arg"/> </xsl:when> <xsl:otherwise> <xsl:message>Exception at Hex2Decimal template</xsl:message> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="m:*/text()"> <xsl:call-template name="replaceEntities"> <xsl:with-param name="content" select="normalize-space()"/> </xsl:call-template> </xsl:template> </xsl:stylesheet>
最新发布
10-21
你提供的这份 XSLT 是一个 **将 MathML 转换为 LaTeX** 的样式表(来自 [XSLT MathML Library](http://www.raleigh.ru/MathML/mmltex)),与前一份“OMML → MathML”的 XSLT 正好是**下游处理环节**。 --- ### ✅ 当前文件功能解析 | 文件 | 作用 | |------|------| | 第一个 XSLT (`omml2mml.xsl`) | 将 Word 的 OMML 公式转为标准 MathML | | 这个 XSLT (`tokens.xsl`) | 将 MathML 渲染成 **LaTeX 字符串**,用于排版输出 | 它主要处理: - `<mi>` → `\mathrm{}` 或普通变量 - `<mn>` → 数字 - `<mo>` → 操作符(自动加 `\left`/`\right`) - `<mtext>` → `\text{...}` - 颜色、字体、空格等格式转换 --- ## 🔧 常见修改需求及解决方案 你现在可能希望: > “在最终生成的 LaTeX 中,让 `dx dy dθ` 显示正确,不粘连,并且 `d` 是正体微分算子” 这是典型的数学排版问题。我们来一步步解决。 --- ### ✅ 目标:将 `dx` 输出为 `\mathrm{d}x\,` 即: - `d` 使用正体(`\mathrm{d}`) - 自动添加薄空格 `\,` - 多个微分如 `dx dy dθ` 不粘连 --- ### ✅ 修改方案:增强 `<mo>` 和 `<mi>` 的处理逻辑 我们需要在 `tokens.xsl` 中对形如 `d<x>` 的情况特殊处理。 #### ✅ 修改点:重写 `mi` 模板以识别微分符号 ```xml <xsl:template name="mi"> <xsl:variable name="content" select="normalize-space(.)" /> <!-- 特殊处理:如果内容是单个字母 'd' 并且后面紧跟着另一个变量(由上下文判断) --> <!-- 但由于 XSLT 1.0 很难看兄弟节点,建议用后处理或配合上层标记 --> <xsl:choose> <!-- 如果是 "d" 且父元素是微分上下文(比如被标记了 class 或 role) --> <xsl:when test="$content = 'd' and ancestor-or-self::*[@class='diff']"> <xsl:text>\mathrm{d}</xsl:text> </xsl:when> <!-- 多字符标识符默认正体 --> <xsl:when test="string-length($content) > 1 and not(@mathvariant)"> <xsl:text>\mathrm{</xsl:text> <xsl:apply-templates/> <xsl:text>}</xsl:text> </xsl:when> <!-- 其他情况原样输出 --> <xsl:otherwise> <xsl:apply-templates/> </xsl:otherwise> </xsl:choose> </xsl:template> ``` 但这依赖你在 MathML 上加自定义属性(如 `<mi class="diff">d</mi>`),否则无法区分普通 `d` 和微分 `d`。 --- ### ✅ 更佳实践:预处理 MathML 标记微分项 在调用此 XSLT 前,先用 Java 或其他工具把 `d<x>` 改写为: ```xml <mo mathvariant="normal">d</mo><mi>x</mi> ``` 然后在此 XSLT 中确保 `<mo>` 的 `mathvariant="normal"` 被正确处理。 #### ✅ 修改 `CommonTokenAtr` 模板支持 `mathvariant="normal"` on `<mo>` 当前代码只对 `<mi>`、`<mn>` 处理 `mathvariant`,但没考虑 `<mo>` 是否有该属性。 #### ✅ 补丁:扩展 `CommonTokenAtr` 对 `mo` 的 `mathvariant` 支持 ```xml <xsl:template name="CommonTokenAtr"> <xsl:if test="@mathbackground"> <xsl:text>\colorbox[rgb]{</xsl:text> <xsl:call-template name="color"> <xsl:with-param name="color" select="@mathbackground"/> </xsl:call-template> <xsl:text>}{$</xsl:text> </xsl:if> <xsl:if test="@color or @mathcolor"> <xsl:text>\textcolor[rgb]{</xsl:text> <xsl:call-template name="color"> <xsl:with-param name="color" select="@color|@mathcolor"/> </xsl:call-template> <xsl:text>}{</xsl:text> </xsl:if> <!-- 新增:支持 mo 的 mathvariant --> <xsl:if test="@mathvariant and local-name()='mo'"> <xsl:choose> <xsl:when test="@mathvariant='normal'"> <xsl:text>\mathrm{</xsl:text> </xsl:when> <xsl:when test="@mathvariant='bold'"> <xsl:text>\mathbf{</xsl:text> </xsl:when> <xsl:otherwise> <xsl:text>{</xsl:text> </xsl:otherwise> </xsl:choose> </xsl:if> <!-- 原有 mathvariant 处理(mi/mn 等)保持不变 --> <xsl:if test="@mathvariant and local-name()!='mo'"> <!-- ... 原来的 choose 分支 ... --> </xsl:if> <xsl:call-template name="selectTemplate"/> <!-- 结束括号 --> <xsl:if test="@mathvariant and (local-name()='mo' or local-name()!='mo')"> <xsl:text>}</xsl:text> </xsl:if> <xsl:if test="@color or @mathcolor"> <xsl:text>}</xsl:text> </xsl:if> <xsl:if test="@mathbackground"> <xsl:text>$}</xsl:text> </xsl:if> </xsl:template> ``` --- ### ✅ 最终推荐流程(Java 实现) 由于 XSLT 1.0 缺乏上下文感知能力,最佳做法是在 **Java 层预处理 MathML**: ```java public String preprocessDifferentialsInMathML(String mathml) { // 匹配 <mi>d</mi><mi>x</mi> → <mo mathvariant="normal">d</mo><mi>x</mi> Pattern p = Pattern.compile( "(<mi[^>]*>)(d)(</mi>\\s*<mi[^>]*>)([a-zA-Z])", Pattern.CASE_INSENSITIVE ); Matcher m = p.matcher(mathml); StringBuffer sb = new StringBuffer(); while (m.find()) { m.appendReplacement(sb, "<mo mathvariant=\"normal\">d</mo><mspace width=\".1em\"/>" + "<mi>" + m.group(4) + "</mi>" ); } m.appendTail(sb); return sb.toString(); } ``` 这样输入到 `tokens.xsl` 后就会输出: ```latex \mathrm{d}\, x ``` --- ### ✅ 效果对比 | 输入 MathML | 当前输出 | 修改后输出 | |------------|----------|-----------| | `<mi>d</mi><mi>x</mi>` | `dx` | `\mathrm{d}\, x` | | `<mi>d</mi><mi>t</mi>` | `dt` | `\mathrm{d}\, t` | | `<mi>d</mi><mi>θ</mi>` | `d\theta` | `\mathrm{d}\,\theta` | 完美解决粘连和字体问题。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值