Как создать XSLT-преобразование для srcML? - PullRequest
0 голосов
/ 01 декабря 2009

У меня вопрос по XSL-преобразованию. Давайте рассмотрим пример (в srcML), который представляет перечисление typedef в C:

<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 Ответ

1 голос
/ 01 декабря 2009

Это немного сложно из-за "вкрапленного текста" природы вашего входного 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...