使用xsl输出数学表达式

发布于 2024-11-08 17:21:51 字数 1475 浏览 6 评论 0原文

我想使用 xslt 从 Mathml 输入输出数学表达式。我的变换一定有什么错误。我不知道如何纠正它。你能帮我吗?我应该使用参数还是变量来控制它? 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>

这是我的 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)

I want to use xslt to output the math expression from Mathml input. There must be some mistake in my transform. I don't know how to correct it. Could you help me? Should I use 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>
</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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

木落 2024-11-15 17:21:51

这个完整而简短的转换

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

This complete and short transformation:

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

produce the wanted, correct result:

eq(plus(power(x,2),times(2,x),2),0)
围归者 2024-11-15 17:21:51

我稍微改变了你原来的转换以获得想要的结果。基本上,apply 模板规则是决定函数括号的规则。为了确定是否插入逗号,我正在检查以下特定类型的同级元素。

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

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


XSLT 1.0Saxon 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::*)>0">
            <xsl:value-of select="','"/>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

当应用于问题中显示的输入时会产生:

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

I've slightly changed your original transform to obtain the wanted result. Basically, the apply template rule it's the one deciding for the function parentesis. To determine whether or not insert a comma I'm checking for following sibling elements of specific types.

Moreover, I've replaced your xsl:sequence with xsl:value-of thus preventing the creation of unwanted spaces (I immagine they are unwanted). Also the function element() has been replaced. The stylesheet is now XSLT 1.0 compatible. I'm not a fun of XSLT 1.0, but I prefer to use new functions only when really necessary.

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


XSLT 1.0 tested under 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::*)>0">
            <xsl:value-of select="','"/>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet>

When applied to the input shown in the question produces:

eq(plus(power(x,2),times(2,x),2),0)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文