1

我有一些形式的 XML:

<definitions devices="myDevice">
    <reg offset="0x0000" mnem="someRegister">
        <field mnem="someField" msb="31" lsb="24 />
        ...
    </reg>
    ...
</definitions>

我希望 XML 成为最终的参考,并使用 XSLT 将其转换为 HTML 用于文档,.h 用于构建(也可能是其他形式)。

HTML 版本运行良好,每个寄存器生成一个表,每个字段一行:

... (header boilerplate removed)
<xsl:for-each select="definitions/reg">
  <table>
    <tr>
      <th><xsl:value-of select="@offset"/></th>
      <th><xsl:value-of select="@mnem"/></th>
    </tr>
    <xsl:for-each select="field">
        <tr>
            <td><xsl:value-of select="@msb"/>..<xsl:value-of select="@lsb"/></td>
            <td><xsl:value-of select="@mnem"/></td>
        </tr>
    </xsl:for-each>
  </table>
</xsl:for-each>

转换为 .h 并不顺利。我完全无法在输出中生成所需的空格:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="definitions/reg">
#define <xsl:value-of select="translate(@mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="@offset"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

我希望它能产生输出:

#define SOMEREGISTER 0x0000

但我实际上得到:

#define SOMEREGISTER0x0000

我不明白为什么我在“#define”之后得到空格,而不是在转换后的助记符之后得到空格。我尝试了一个更简单的解决方案,只有一个内联空间,结果相同。

我对此(XSLT)太陌生了,不知道我是a)做错了还是b)在tDOM中找到了限制。

4

3 回答 3

2

用这个测试:

# I could have read these from a file I suppose...
set in {<definitions devices="myDevice">
<reg offset="0x0000" mnem="someRegister">
<field mnem="someField" msb="31" lsb="24" />
</reg>
</definitions>}
set ss {<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="definitions/reg">
<xsl:text>#define </xsl:text>
<xsl:value-of select="translate(@mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<xsl:text xml:space="preserve"> </xsl:text>
<xsl:value-of select="@offset"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>}

# Interesting code starts here
package require tdom
set indoc [dom parse $in]
set xslt [dom parse -keepEmpties $ss]
set outdoc [$indoc xslt $xslt]
puts [$outdoc asText]

我发现这行得通。问题是 tDOM 解析器没有xml:space正确处理属性;如果没有神奇的-keepEmpties选项,所有空字符串都会从样式表中删除,这会导致应用错误的 XSLT 样式表。但是有了这个选项,它似乎做了正确的事情。

请注意,XSLT 引擎本身正在做正确的事情。它是 XML 解析器/DOM 构建器。(我认为这是一个错误;我会查找在哪里报告它。)

于 2011-10-27T15:04:06.553 回答
0

您没有在第二个样式表中指定输出方法,因此默认为 XML。我建议您使用输出方法“文本”,然后将<xsl:text>元素用于任何文字输出。检查这个例子:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/">
        <xsl:for-each select="definitions/reg"><xsl:text>#define </xsl:text><xsl:value-of select="translate(@mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:text> </xsl:text><xsl:value-of select="@offset"/><xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

编辑:顺便说一句,&#10;最后是一个字符代码。它只是换行的 ASCII 码的十进制值。这可以确保您为下一个 reg 条目开始一个新行。如果您需要 Windows/DOS 约定(回车 + 换行),请&#13;&#10;改用。

于 2011-10-26T20:46:23.933 回答
0

每: http ://www.ibm.com/developerworks/xml/library/x-tipwhitesp/index.html

尝试使用保留空间指令:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="definitions/reg">
    <xsl:text xml:space="preserve">#define </xsl:text>
    <xsl:value-of select="translate(@mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    <xsl:text xml:space="preserve"> </xsl:text>
    <xsl:value-of select="@offset"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
于 2011-10-26T20:41:16.530 回答