我正在尝试进行生成C代码的XSLT转换,应转换以下XML:
<enum name="anenum">
<enumValue name="a"/>
<enumValue name="b"/>
<enumValue name="c" data="10"/>
<enumValue name="d" />
<enumValue name="e" />
</enum>
Run Code Online (Sandbox Code Playgroud)
它应转换为以下C代码:
enum anenum {
a = 0,
b = 1,
c = 10,
d = 11,
e = 12
}
Run Code Online (Sandbox Code Playgroud)
或替代(因为C预处理器将处理求和):
enum anenum {
a = 0,
b = 1,
c = 10,
d = c+1,
e = c+2
}
Run Code Online (Sandbox Code Playgroud)
我的XSLT的核心看起来像:
<xsl:for-each select="enumValue">
<xsl:value-of select="name"/>
<xsl:text> = </xsl:text>
<xsl:choose>
<xsl:when test="string-length(@data)>0">
<xsl:value-of select="@data"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="position()-1"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text>,
Run Code Online (Sandbox Code Playgroud)
(为简单起见,我跳过了一些“最后一个元素不加逗号”的代码)
本示例将不会为d和e生成正确的值
我一直在努力让它适用于变量d和e,但到目前为止我还没有成功。
使用如下结构:
<xsl:when test="string-length(preceding-sibling::enumValue[1]/@datavalue)>0">
<xsl:value-of select="preceding-sibling::enumValue/@data + 1"/>
</xsl:when>
Run Code Online (Sandbox Code Playgroud)
...仅适用于指定值(在本例中为d)之后的第一个。
谁能帮我?我可能在程序上想得太多...
使用键的非递归解决方案:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="text"/>
<xsl:key name="koffsetEnums" match="enumValue[@data]"
use="generate-id()"/>
<xsl:template match="enum">
enum <xsl:value-of select="@name"/> {
<xsl:apply-templates select="enumValue"/>
}
</xsl:template>
<xsl:template match="enumValue">
<xsl:value-of select="concat(@name, ' = ')"/>
<xsl:variable name="voffsetValueId" select=
"generate-id((. | preceding-sibling::enumValue)
[@data][last()]
)"/>
<xsl:choose>
<xsl:when test="not($voffsetValueId)">
<xsl:value-of select="concat(position(),'
 ')"/>
</xsl:when>
<xsl:otherwise>
<xsl:variable name="vinitOffset" select=
"key('koffsetEnums', $voffsetValueId)/@data"
/>
<xsl:value-of select=
"$vinitOffset
+
count(preceding-sibling::enumValue)
-
count(key('koffsetEnums', $voffsetValueId)/preceding-sibling::enumValue)
"
/>
<xsl:text>
 </xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当上述转换应用于最初提供的 XML 文档时:
<enum name="anenum">
<enumValue name="a"/>
<enumValue name="b"/>
<enumValue name="c" data="10"/>
<enumValue name="d" />
<enumValue name="e" />
</enum>
Run Code Online (Sandbox Code Playgroud)
产生所需的结果:
enum anenum {
a = 1
b = 2
c = 10
d = 11
e = 12
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2781 次 |
| 最近记录: |