在C#中使用OpenMath转换为MathML

时间:2015-09-23 18:41:48

标签: c# .net mathml

我正在尝试创建方程式文本框。为此我找到了mathdox编辑器,我用它以图形方式预览方程并将其转换为mathml以便稍后在网页上预览方程式。 问题是如何在c#中将OpenMath转换为MathML?我在javascript中很糟糕,所以我更喜欢将openmath代码发送到服务器并处理其中的所有内容。有没有人这样做过?

1 个答案:

答案 0 :(得分:1)

OpenMath和MathML都是基于xml的标记语言,因此要将一个转换为另一个,首先想到的是xsl转换。经过一些研究后,你可以找到xslt样式表来做here(参见" XSLT样式表,用于OpenMath和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样式表将转换为内容版本。但是,如果您需要演示文稿版本,则上面的同一网站具有将内容转换为演示文稿的样式表,因此您可以通过应用两个转换将OpenMath转换为Presentation MathML。