использование xsl для вывода математического выражения

Я хочу использовать 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)

person ZAWD    schedule 21.05.2011    source источник
comment
@empo, я должен задаться вопросом, должны ли ваши правки быть включены в ответ, а не в вопрос; такое ощущение, что ты знаешь, что делаешь :), но я не знаю, почему ты это делаешь. :)   -  person sarnold    schedule 22.05.2011
comment
@sarnold: это должны быть безопасные правки, которые проясняют вопрос. Я добавил недостающую часть кода в xslt, который объявляет используемую версию. Я установил версию 2.0, потому что OP использует элементы и функции XSLT 2.0.   -  person Emiliano Poggi    schedule 22.05.2011
comment
@pst, 1.0 был в первом редактировании @empo, не предоставленном исходным сообщением @ZAWD. :)   -  person sarnold    schedule 22.05.2011
comment
Да, извините, ребята, что внесли несколько изменений вместо одного :) и спасибо, что приняли их.   -  person Emiliano Poggi    schedule 22.05.2011
comment
Хороший вопрос, +1. Смотрите мой ответ для полного и самого простого и кратчайшего (на данный момент) решения. :)   -  person Dimitre Novatchev    schedule 22.05.2011


Ответы (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)
person Dimitre Novatchev    schedule 21.05.2011
comment
не могли бы вы помочь мне снова. У меня есть новый вопрос по этому поводу: в моем xsl о mathml"> stackoverflow.com/questions/6113865/ - person ZAWD; 24.05.2011

Я немного изменил ваше исходное преобразование, чтобы получить желаемый результат. По сути, правило шаблона apply определяет скобки функции. Чтобы определить, вставлять ли запятую, я проверяю наличие следующих родственных элементов определенных типов.

Кроме того, я заменил ваш xsl:sequence на xsl:value-of, тем самым предотвратив создание нежелательных пробелов (мне кажется, они нежелательны). Также была заменена функция element(). Таблица стилей теперь совместима с XSLT 1.0. Мне не нравится XSLT 1.0, но я предпочитаю использовать новые функции только тогда, когда это действительно необходимо.

Это решение не очень общее (вы знаете, MATHML — огромная спецификация), но вы можете использовать его и адаптировать к более сложным случаям.


XSLT 1.0 протестирован в 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>

При применении к входу, указанному в вопросе, получается:

eq(plus(power(x,2),times(2,x),2),0)
person Emiliano Poggi    schedule 21.05.2011