在 C# 中将 Open Math 转换为 MathML
Conver OpenMath to MathML in C#
我正在尝试创建公式文本框。为此,我找到了 mathdox 编辑器,我用它来以图形方式预览方程式并将其转换为 mathml,以便稍后在网页上预览方程式。
问题是如何在 C# 中将 OpenMath 转换为 MathML?我在 javascript 方面很糟糕,所以我更喜欢将 openmath 代码发送到服务器并在那里处理所有内容。有人做过吗?
OpenMath 和 MathML 都是基于 xml 的标记语言,因此将一种语言转换为另一种语言首先想到的是 xsl 转换。经过一些研究后,您可以找到 xslt 样式表来执行此操作 here(请参阅 "XSLT stylesheets for conversion between OpenMath and Content MathML" 部分)。在该 zip 存档中有 4 个文件,您需要 "omtocmml.xsl"。
现在让我们从维基百科中获取示例 OpenMath:
<OMOBJ xmlns="http://www.openmath.org/OpenMath">
<OMA cdbase="http://www.openmath.org/cd">
<OMS cd="relation1" name="eq"/>
<OMV name="x"/>
<OMA>
<OMS cd="arith1" name="divide"/>
<OMA>
<OMS cdbase="http://www.example.com/mathops" cd="multiops" name="plusminus"/>
<OMA>
<OMS cd="arith1" name="unary_minus"/>
<OMV name="b"/>
</OMA>
<OMA>
<OMS cd="arith1" name="root"/>
<OMA>
<OMS cd="arith1" name="minus"/>
<OMA>
<OMS cd="arith1" name="power"/>
<OMV name="b"/>
<OMI>2</OMI>
</OMA>
<OMA>
<OMS cd="arith1" name="times"/>
<OMI>4</OMI>
<OMV name="a"/>
<OMV name="c"/>
</OMA>
</OMA>
</OMA>
</OMA>
<OMA>
<OMS cd="arith1" name="times"/>
<OMI>2</OMI>
<OMV name="a"/>
</OMA>
</OMA>
</OMA>
</OMOBJ>
这里是应用转换的示例代码(假设您使用 OpenMath 将字符串传递给它,并假设 omtocmml.xsl 在应用程序目录中)。请注意,这只是一个示例,在现实生活中您可能希望将 xsl 存储在程序集资源中,也可能希望使用一个预编译的 XslCompiledTransform 而不是每次都创建它。
public static string OpenMathToMathML(string source) {
var trans = new XslCompiledTransform();
using (var fs = File.OpenRead("omtocmml.xsl")) {
var settings = new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Parse
};
using (var schemaReader = XmlReader.Create(fs, settings)) {
trans.Load(schemaReader);
using (var ms = new MemoryStream()) {
using (var sreader = new StringReader(source)) {
using (var reader = XmlReader.Create(sreader)) {
trans.Transform(reader, null, ms);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
}
}
}
}
对于上面的示例 OpenMath,它生成以下 MathML 输出:
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<eq />
<ci>x</ci>
<apply>
<divide />
<apply>
<csymbol definitionURL="http://www.openmath.org/cd/multiops#plusminus" />
<apply>
<minus />
<ci>b</ci>
</apply>
<apply>
<root />
<degree />
<apply>
<minus />
<apply>
<power />
<ci>b</ci>
<cn type="integer">2</cn>
</apply>
<apply>
<times />
<cn type="integer">4</cn>
<ci>a</ci>
<ci>c</ci>
</apply>
</apply>
</apply>
</apply>
<apply>
<times />
<cn type="integer">2</cn>
<ci>a</ci>
</apply>
</apply>
</apply>
</math>
最后一点:请注意 MathML 有两个版本 - Presentation 和 Content。 omtocmml.xsl 样式表将转换为内容版本。但是,如果您需要 Presentation 版本,上面的同一网站具有将 Content 转换为 Presentation 的样式表,因此您可以通过应用两个转换将 OpenMath 转换为 Presentation MathML。
我正在尝试创建公式文本框。为此,我找到了 mathdox 编辑器,我用它来以图形方式预览方程式并将其转换为 mathml,以便稍后在网页上预览方程式。 问题是如何在 C# 中将 OpenMath 转换为 MathML?我在 javascript 方面很糟糕,所以我更喜欢将 openmath 代码发送到服务器并在那里处理所有内容。有人做过吗?
OpenMath 和 MathML 都是基于 xml 的标记语言,因此将一种语言转换为另一种语言首先想到的是 xsl 转换。经过一些研究后,您可以找到 xslt 样式表来执行此操作 here(请参阅 "XSLT stylesheets for conversion between OpenMath and Content MathML" 部分)。在该 zip 存档中有 4 个文件,您需要 "omtocmml.xsl"。
现在让我们从维基百科中获取示例 OpenMath:
<OMOBJ xmlns="http://www.openmath.org/OpenMath">
<OMA cdbase="http://www.openmath.org/cd">
<OMS cd="relation1" name="eq"/>
<OMV name="x"/>
<OMA>
<OMS cd="arith1" name="divide"/>
<OMA>
<OMS cdbase="http://www.example.com/mathops" cd="multiops" name="plusminus"/>
<OMA>
<OMS cd="arith1" name="unary_minus"/>
<OMV name="b"/>
</OMA>
<OMA>
<OMS cd="arith1" name="root"/>
<OMA>
<OMS cd="arith1" name="minus"/>
<OMA>
<OMS cd="arith1" name="power"/>
<OMV name="b"/>
<OMI>2</OMI>
</OMA>
<OMA>
<OMS cd="arith1" name="times"/>
<OMI>4</OMI>
<OMV name="a"/>
<OMV name="c"/>
</OMA>
</OMA>
</OMA>
</OMA>
<OMA>
<OMS cd="arith1" name="times"/>
<OMI>2</OMI>
<OMV name="a"/>
</OMA>
</OMA>
</OMA>
</OMOBJ>
这里是应用转换的示例代码(假设您使用 OpenMath 将字符串传递给它,并假设 omtocmml.xsl 在应用程序目录中)。请注意,这只是一个示例,在现实生活中您可能希望将 xsl 存储在程序集资源中,也可能希望使用一个预编译的 XslCompiledTransform 而不是每次都创建它。
public static string OpenMathToMathML(string source) {
var trans = new XslCompiledTransform();
using (var fs = File.OpenRead("omtocmml.xsl")) {
var settings = new XmlReaderSettings
{
DtdProcessing = DtdProcessing.Parse
};
using (var schemaReader = XmlReader.Create(fs, settings)) {
trans.Load(schemaReader);
using (var ms = new MemoryStream()) {
using (var sreader = new StringReader(source)) {
using (var reader = XmlReader.Create(sreader)) {
trans.Transform(reader, null, ms);
return Encoding.UTF8.GetString(ms.ToArray());
}
}
}
}
}
}
对于上面的示例 OpenMath,它生成以下 MathML 输出:
<math xmlns="http://www.w3.org/1998/Math/MathML">
<apply>
<eq />
<ci>x</ci>
<apply>
<divide />
<apply>
<csymbol definitionURL="http://www.openmath.org/cd/multiops#plusminus" />
<apply>
<minus />
<ci>b</ci>
</apply>
<apply>
<root />
<degree />
<apply>
<minus />
<apply>
<power />
<ci>b</ci>
<cn type="integer">2</cn>
</apply>
<apply>
<times />
<cn type="integer">4</cn>
<ci>a</ci>
<ci>c</ci>
</apply>
</apply>
</apply>
</apply>
<apply>
<times />
<cn type="integer">2</cn>
<ci>a</ci>
</apply>
</apply>
</apply>
</math>
最后一点:请注意 MathML 有两个版本 - Presentation 和 Content。 omtocmml.xsl 样式表将转换为内容版本。但是,如果您需要 Presentation 版本,上面的同一网站具有将 Content 转换为 Presentation 的样式表,因此您可以通过应用两个转换将 OpenMath 转换为 Presentation MathML。