Using xsl to output a mathematical expression

I want to use xslt to output a math expression from Mathml input. There must be some kind of error in my conversion. I do not know how to fix this. Could you help me? Should I use a parameter or variable to control it? XML:

<?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> 

This is my 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> 

The result should be:

  eq (plus (power (x, 2), times (2, x), 2), 0)
+4
source share
2 answers

This is a complete and short conversion :

 <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> 

when applied to the provided XML document :

 <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> 

create the desired, correct result :

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

I slightly modified the original transformation to get the desired result. Basically, the apply template rule is a solution that solves the parentesis function. To determine whether to insert or not to insert a comma, I check the following sibling elements of different types.

In addition, I replaced your xsl:sequence with xsl:value-of , thereby preventing the creation of unwanted spaces (I am impressed that they are undesirable). The element() function has also been replaced. The style sheet is now compatible with XSLT 1.0. I don't like XSLT 1.0, but I prefer to use new features only when it's really needed.

This solution is not very general (MATHML is a huge specification that you know), but you can use it and adapt it to more complex cases.


XSLT 1.0 is being tested in Saxon 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> 

When applied to the input shown in the question, the following occurs:

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

All Articles