将MathML解析为简单的数学表达式

时间:2014-10-14 09:24:06

标签: javascript c# parsing expression mathml

我正在使用MathDox公式编辑器来生成MathML。现在我想将MathDox生成的MathML转换为表达式,我稍后可以用它来评估以找到答案。

For eg:

MathML:
<math xmlns='http://www.w3.org/1998/Math/MathML'>
 <mrow>
  <mn>3</mn>
  <mo>+</mo>
  <mn>5</mn>
 </mrow>
</math>

Want to convert to expression as:
3+5

现在我可以使用3 + 5来获得答案8.

我正在搜索此转换的 javascript c#解决方案。试图google它,但没有得到太多的帮助。我找到了here更接近的解决方案,但它也是一个桌面应用程序,也是商业用途。但是,我想要解决我的问题的开源Web应用程序解决方案。任何帮助将不胜感激。

注意:为简单起见,我在上面的示例中仅提到了简单的添加,但mathml也可以包含复杂的表达式,例如派生和日志。

1 个答案:

答案 0 :(得分:3)

这可以通过JavaScript中的以下步骤来实现:

  1. 从MathML转换为XML DOM
  2. 从XML DOM转换为纯文本
  3. 使用“eval”函数获取表达式的十进制值
  4. 以下代码正是如此:

    function getDOM(xmlstring) {
        parser=new DOMParser();
        return parser.parseFromString(xmlstring, "text/xml");
    }
    
    function remove_tags(node) {
        var result = "";
        var nodes = node.childNodes;
        var tagName = node.tagName;
        if (!nodes.length) {
            if (node.nodeValue == "π") result = "pi";
            else if (node.nodeValue == " ") result = "";
            else result = node.nodeValue;
        } else if (tagName == "mfrac") {
            result = "("+remove_tags(nodes[0])+")/("+remove_tags(nodes[1])+")";
        } else if (tagName == "msup") {
            result = "Math.pow(("+remove_tags(nodes[0])+"),("+remove_tags(nodes[1])+"))";
        } else for (var i = 0; i < nodes.length; ++i) {
            result += remove_tags(nodes[i]);
        }
    
        if (tagName == "mfenced") result = "("+result+")";
        if (tagName == "msqrt") result = "Math.sqrt("+result+")";
    
        return result;
    }
    
    function stringifyMathML(mml) {
       xmlDoc = getDOM(mml);
       return remove_tags(xmlDoc.documentElement);
    }
    
    // Some testing
    
    s = stringifyMathML("<math><mn>3</mn><mo>+</mo><mn>5</mn></math>");
    alert(s);
    alert(eval(s));
    
    s = stringifyMathML("<math><mfrac><mn>1</mn><mn>2</mn></mfrac><mo>+</mo><mn>1</mn></math>");
    alert(s);
    alert(eval(s));
    
    s = stringifyMathML("<math><msup><mn>2</mn><mn>4</mn></msup></math>");
    alert(s);
    alert(eval(s));
    
    s = stringifyMathML("<math><msqrt><mn>4</mn></msqrt></math>");
    alert(s);
    alert(eval(s));
    

    按照上面的代码,可以扩展接受的MathML。例如,添加三角函数或任何其他自定义函数会很容易。

    出于本文的目的,我使用了mathml editor中的工具来构建MathML(在代码的测试部分中使用)。