如何为srcML创建XSLT转换?

时间:2009-12-01 09:37:03

标签: xslt

我对XSL转换有疑问。让我们举一个例子(在srcML中),它代表C:

中的typedef枚举
<typedef>typedef <type><enum>enum <name>SomeEnum</name>
<block>{
 <expr><name>Value0</name> = 0</expr>,
 <expr><name>Value1</name> = <name>SOMECONST</name></expr>,
 <expr><name>Value2</name> = <name>SOMECONST</name> + 1</expr>,
 <expr><name>ValueTop</name></expr>
}</block></enum></type> <name>TSomeEnum</name>;</typedef>

C版:

typedef enum SomeEnum
{
    Value0 = 0,
    Value1 = SOMECONST,
    Value2 = SOMECONST + 1,
    ValueTop
} TSomeEnum;

如何定义<xsl:template>以删除该行,例如Value2

如何定义<xsl:template>以删除最后一行(使用ValueTop),包括前面的逗号?

1 个答案:

答案 0 :(得分:1)

由于输入XML的“散布文本”性质,这有点棘手。特别是逗号处理并不简单,我提出的解决方案可能是错误的(即使它适用于这个特定的输入)。我建议更多考虑逗号处理部分,因为C语法很复杂,我对srcML知之甚少。

无论如何,这是我的尝试。

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:src="http://www.sdml.info/srcML/src"
  xmlns="http://www.sdml.info/srcML/src"
>
  <!-- the identity template copies everything as is -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <!-- empty templates will remove any matching elements from the output -->
  <xsl:template match="src:expr[src:name = 'Value2']" />
  <xsl:template match="src:expr[last()]" />

  <!-- this template handles the commata after expressions -->
  <xsl:template match="text()[normalize-space() = ',']">
    <!-- select the following node, but only if it is an <expr> element -->
    <xsl:variable name="expr" select="following-sibling::*[1][self::src:expr]" />

    <!-- apply templates to it, save the result -->
    <xsl:variable name="check">
      <xsl:apply-templates select="$expr" />
    </xsl:variable>

    <!-- if something was returned, then this comma needs to be copied -->
    <xsl:if test="$check != ''">
      <xsl:copy />
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

我的输入是(为了示例,我使用了srcML命名空间):

<unit xmlns="http://www.sdml.info/srcML/src">
<typedef>typedef <type><enum>enum <name>SomeEnum</name>
<block>{
 <expr><name>Value0</name> = 0</expr>,
 <expr><name>Value1</name> = <name>SOMECONST</name></expr>,
 <expr><name>Value2</name> = <name>SOMECONST</name> + 1</expr>,
 <expr><name>ValueTop</name></expr>
}</block></enum></type> <name>TSomeEnum</name>;</typedef>
</unit

结果:

<unit xmlns="http://www.sdml.info/srcML/src">
<typedef>typedef <type><enum>enum <name>SomeEnum</name>
<block>{
 <expr><name>Value0</name> = 0</expr>,
 <expr><name>Value1</name> = <name>SOMECONST</name></expr>
}</block></enum></type> <name>TSomeEnum</name>;</typedef>
</unit>