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]

これでうまくいくことがわかりました。xml:space問題は、tDOMパーサーが属性を正しく処理しないことです。魔法の-keepEmptiesオプションがないと、すべての空の文字列がスタイルシートから削除され、間違ったXSLTスタイルシートが適用されることになります。しかしオプションを使用すると、それは正しいことをしているように見えます。

XSLTエンジン自体が正しいことをしていることに注意してください。これは、XMLパーサー/DOMビルダーです。(これはバグだと思います。どこに報告するか調べます。)

于 2011-10-27T15:04:06.553 に答える
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 に答える
0

2番目のスタイルシートで出力メソッドが指定されていないため、デフォルトはXMLになります。出力メソッド「text」を使用し<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コードの10進値です。これにより、次のregエントリの新しい行を開始することができます。Windows / DOS規則(キャリッジリターン+ラインフィード)が必要な場合は、&#13;&#10;代わりに使用してください。

于 2011-10-26T20:46:23.933 に答える