4

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

2 に答える 2

2

必要な結果を得るために、元の変換を少し変更しました。基本的に、applyテンプレート ルールは、関数の括弧を決定するものです。コンマを挿入するかどうかを判断するために、次の特定のタイプの兄弟要素をチェックしています。

さらに、あなたを置き換えてxsl:sequencexsl: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)
于 2011-05-21T21:33:40.627 に答える
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)
于 2011-05-21T22:41:38.823 に答える