2011-05-21 64 views
4

我想使用xslt从Mathml输入输出数学表达式。我的转变肯定有一些错误。我不知道如何纠正它。你可以帮帮我吗?我应该使用参数还是变量来控制它? XML:使用xsl输出数学表达式

<?xml version="1.0" encoding="UTF-8"?> 

<math> 
    <apply> 
    <eq/> 
    <apply> 
     <plus/> 
     <apply> 
     <power/> 
     <ci>x</ci> 
     <cn>2</cn> 
     </apply> 
     <apply> 
     <times/> 
     <cn>2</cn> 
     <ci>x</ci> 
     </apply> 
     <cn>2</cn> 
    </apply> 
    <cn>0</cn> 
    </apply> 
</math> 

这是我的xsl:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="text" encoding="UTF-8"/> 

    <xsl:template match="/"> 
    <xsl:apply-templates/> 
    <xsl:text>&#10;</xsl:text> 
    </xsl:template> 

    <xsl:template match="math"> 
      <xsl:apply-templates select="apply"/> 
    </xsl:template> 

    <xsl:template match="apply"> 

     <xsl:sequence select="name(element()[1]),'('"/> 
     <xsl:apply-templates select="apply"> 
     </xsl:apply-templates> 
     <xsl:sequence select="element()[2],','"/> 
     <xsl:sequence select="element()[3],')',','"/> 

    </xsl:template> 

</xsl:stylesheet> 

结果应该是:

 
    eq(plus(power(x,2),times(2,x),2),0) 
+0

@empo,我想知道,如果你的编辑应该有被包括在答案中而不是问题中;感觉就像你知道你在做什么:)但我不知道你是否在做他们。 :) – sarnold 2011-05-21 21:25:23

+0

@sarnold:他们应该是安全的编辑,这使问题变得清晰。我已将缺少的部分代码添加到声明所用版本的xslt中。我设置了2.0版本,因为OP使用了XSLT 2.0中的元素和功能。 – 2011-05-21 21:36:40

+0

@empo,优秀!谢谢。 :) – sarnold 2011-05-21 21:39:53

回答

2

这个完整的和短的转化

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="apply"> 
    <xsl:if test="not(position()=1)">,</xsl:if> 
    <xsl:apply-templates select="*[1]"/> 
</xsl:template> 

<xsl:template match="eq|plus|power|times"> 
    <xsl:if test="not(position()=1)">,</xsl:if> 
    <xsl:value-of select="concat(name(), '(')"/> 
    <xsl:apply-templates select="following-sibling::*"/> 
    <xsl:text>)</xsl:text> 
</xsl:template> 

<xsl:template match="cn|ci"> 
    <xsl:if test="not(position()=1)">,</xsl:if> 
    <xsl:value-of select="."/> 
</xsl:template> 
</xsl:stylesheet> 

时所提供的XML文档应用:

<math> 
    <apply> 
     <eq/> 
     <apply> 
      <plus/> 
      <apply> 
       <power/> 
       <ci>x</ci> 
       <cn>2</cn> 
      </apply> 
      <apply> 
       <times/> 
       <cn>2</cn> 
       <ci>x</ci> 
      </apply> 
      <cn>2</cn> 
     </apply> 
     <cn>0</cn> 
    </apply> 
</math> 

产生想要的,正确的结果

eq(plus(power(x,2),times(2,x),2),0) 
+0

你总是给我美好的回答!谢谢!! – ZAWD 2011-05-24 16:32:11

+0

你能帮我一下吗?我有一个新的问题:http://stackoverflow.com/questions/6113865/some-problems-in-my-xsl-about-mathml – ZAWD 2011-05-24 16:45:47

2

我已经略有改变你原来的变换,以获得想要的结果。基本上,apply模板规则是决定函数parentesis的一个规则。要确定是否插入逗号,我将检查以下特定类型的同胞元素。

此外,我已将xsl:sequence替换为xsl:value-of,从而防止创建不需要的空间(我想它们是不需要的)。此外,功能element()已被替换。样式表现在与XSLT 1.0兼容。我不是XSLT 1.0的乐趣,但我更喜欢只在真正需要时才使用新函数。

这个解决方案不是非常普遍的(MATHML是你知道的一个很大的规范),但是你可以使用它并且适应更复杂的情况。


XSLT 1.0下测试撒克逊6.5.5

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" encoding="UTF-8"/> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="apply"> 
     <xsl:value-of select="concat(name(child::*[1]),'(')"/> 
     <xsl:apply-templates select="apply|cn|ci"/> 
     <xsl:value-of select="')'"/> 
     <xsl:if test="count(following-sibling::*)"> 
      <xsl:value-of select="','"/> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="cn|ci"> 
     <xsl:value-of select="."/> 
     <xsl:if test="count(following-sibling::*)&gt;0"> 
      <xsl:value-of select="','"/> 
     </xsl:if> 
    </xsl:template> 

</xsl:stylesheet> 

当施加到在问题所示的输入产生:

eq(plus(power(x,2),times(2,x),2),0)