0

次のような XML があります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<variablelist>
    <varinfo id="id-5">
        <vardef>
            <name>A</name>
            <init>
                <compoundinit type="composite">
                    <singleinit>(unsigned char)6</singleinit>
                    <singleinit>(unsigned char)0</singleinit>
                    <compoundinit type="array">
                        <singleinit>(short)400</singleinit>
                        <singleinit>(short)600</singleinit>
                        <singleinit>(short)800</singleinit>
                    </compoundinit>
                    <compoundinit type="array">
                        <singleinit>(short)32767</singleinit>
                        <singleinit>(short)32767</singleinit>
                        <singleinit>(short)32767</singleinit>
                    </compoundinit>
                </compoundinit>
            </init>
        </vardef>
    </varinfo>
    <varinfo id="id-10">
        <vardef>
            <name>B</name>
            <init>
                <compoundinit type="array">
                    <singleinit>(uint32 const volatile)0U</singleinit>
                    <singleinit>(uint32 const volatile)0U</singleinit>
                    <singleinit>(uint32 const volatile)0U</singleinit>
                    <singleinit>(uint32 const volatile)0U</singleinit>
                </compoundinit>
            </init>
        </vardef>
    </varinfo>
    <varinfo id="id-200">
        <vardef>
            <name>C</name>
            <init>
                <compoundinit type="composite">
                    <singleinit>(unsigned char)12</singleinit>
                    <singleinit>(unsigned char)12</singleinit>
                    <compoundinit type="array">
                        <singleinit>(short)900</singleinit>
                        <singleinit>(short)1000</singleinit>
                        <singleinit>(short)1240</singleinit>
                        <singleinit>(short)1750</singleinit>
                    </compoundinit>
                    <compoundinit type="array">
                        <singleinit>(short)512</singleinit>
                        <singleinit>(short)640</singleinit>
                        <singleinit>(short)853</singleinit>
                        <singleinit>(short)1067</singleinit>
                        <singleinit>(short)1280</singleinit>
                    </compoundinit>
                    <compoundinit type="array">
                        <compoundinit type="array">
                            <singleinit>(unsigned char)153</singleinit>
                            <singleinit>(unsigned char)153</singleinit>
                            <singleinit>(unsigned char)153</singleinit>
                            <singleinit>(unsigned char)153</singleinit>
                        </compoundinit>
                        <compoundinit type="array">
                            <singleinit>(unsigned char)153</singleinit>
                            <singleinit>(unsigned char)153</singleinit>
                            <singleinit>(unsigned char)153</singleinit>
                            <singleinit>(unsigned char)153</singleinit>
                        </compoundinit>
                    </compoundinit>
                </compoundinit>
            </init>
        </vardef>
    </varinfo>
</variablelist>

私がやりたいことは、変数の使用済みビットを合計することです。したがって、たとえば変数 A は、2 つの「unsigned char」データ型と 6 つの「short」データ型で構成されます。「short」が 16 ビット、「char」が 8 ビットと仮定します。したがって、変数 A は 112 ビット (6*16 + 2*8) です。

次の出力が必要な場合、XSLT ファイルはどのようになりますか。

<?xml version="1.0" encoding="UTF-8"?>
<variablelist>
    <varinfo>
            <name>A</name>
            <size>112</size>
    </varinfo>
    <varinfo>
            <name>B</name>
            <size>128</size>
    </varinfo>
    <varinfo>
            <name>C</name>
            <size>224</size>
    </varinfo>
</variablelist>

現時点では、少なくとも次の出力を達成することができました。

<?xml version="1.0" encoding="UTF-8"?>
<variablelist>
   <varinfo>
      <name>A</name>
      <size>(unsigned char)6(unsigned char)0(short)400(short)600(short)800(short)32767(short)32767(short)32767</size>
   </varinfo>
   <varinfo>
      <name>B</name>
      <size>(uint32 const volatile)0U(uint32 const volatile)0U(uint32 const volatile)0U(uint32 const volatile)0U</size>
   </varinfo>
   <varinfo>
      <name>C</name>
      <size>(unsigned char)12(unsigned char)12(short)900(short)1000(short)1240(short)1750(short)512(short)640(short)853(short)1067(short)1280(unsigned char)153(unsigned char)153(unsigned char)153(unsigned char)153(unsigned char)153(unsigned char)153(unsigned char)153(unsigned char)153</size>
   </varinfo>
</variablelist>

この変換コードでは:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/">
        <variablelist>
            <xsl:apply-templates select="/variablelist"/>
        </variablelist>
    </xsl:template>

    <xsl:template match="variablelist">
        <xsl:for-each select="varinfo">
            <varinfo>
                <xsl:choose>
                    <xsl:when test="not(current()/vardef/init)">
                        <!-- ... -->
                    </xsl:when>

                    <xsl:when test="current()/vardef/init">
                        <xsl:choose>
                            <xsl:when test="current()/vardef/init/singleinit">
                                <!-- ... -->
                            </xsl:when>

                            <xsl:otherwise>
                                <name>
                                    <xsl:value-of select="current()/vardef/name/."/>
                                </name>
                                <size>
                                    <xsl:for-each select="current()/vardef/init//node()">
                                        <xsl:if test="name() = 'singleinit'">
                                            <xsl:value-of select="."/>
                                        </xsl:if>
                                    </xsl:for-each>
                                </size>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:when>

                    <xsl:otherwise>
                        <!-- ... -->
                    </xsl:otherwise>
                </xsl:choose>
            </varinfo>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

文字列を数値に変換するには、次のようなものを使用します。

<xsl:when test="contains((substring-before((current()/vardef/init/singleinit/.),')')),'char')"> 
    <xsl:value-of select="'8'"/> 
</xsl:when> 

私の問題を解決する方法を知っている人はいますか? 変数またはパラメーターを使用してさまざまな方法を試しましたが、これまでのところ成功していません。

ありがとう!

PS .: ここでの最初の質問です。あなたのネチケットに正しく従っていただければ幸いです。そして、誰かがより良いタイトルのアイデアを持っていますか?

4

1 に答える 1

1

これを試して:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="varinfo">
        <xsl:copy>
            <xsl:copy-of select="vardef/name"/>
            <size>
                <xsl:value-of select="8 *count( descendant::singleinit[ contains(.,'(unsigned char)') ] ) +
                            16 * count( descendant::singleinit[ contains(.,'(short)') ] ) +
                            32 *count( descendant::singleinit[ contains(.,'(uint32 const volatile)' ) ] )"/>
            </size>
        </xsl:copy>

    </xsl:template>
</xsl:stylesheet>

次の出力が生成されます。

<?xml version="1.0"?>
<variablelist>
        <varinfo><name>A</name><size>112</size></varinfo>
        <varinfo><name>B</name><size>128</size></varinfo>
        <varinfo><name>C</name><size>224</size></varinfo>
</variablelist>

コメント: ご要望に応じて:文字列を数値に変換するには、次のようなものを使用します(xsl:when for bit size)。私はそれをお勧めしません。これは物事をより複雑にするだけです。最終的な解決策に応じて可能な拡張機能は次のとおりです。
- 計算を名前付きテンプレートに移動します。
- 署名付きと未署名を区別しないように、contains 操作を適合させます。

于 2013-05-16T15:23:07.413 に答える