0

1 つのリストにコンパイルしたい定義を含む一連のファイルがあります。ファイルのリストは、次のような XML ファイルに保存されます (これが入力ファイルです)。

 <report>
 <incident>
 <file>Balance_fields_selected.htm</file>
 </incident>
 <incident>
 <file>Cd_fields.htm</file>
 </incident>
 </report>

要素で指定された各ファイルには、単一のリストにコンパイルする必要が<file>ある一連の要素が含まれています。<p class='Term'>これらのそれぞれの後に、グループ化する必要がある任意の数の他の要素が続きます (キーを使用しようとしています)。

 <html><body>
 <p class="Term">
<a name="Accrued_Bonus_Interest" id="Accrued_Bonus_Interest"></a>Accrued (Bonus Interest)</p>
<p>Bonus Interest Accrued Cycle-to-Date. &#160;Amount of bonus interest that has accrued on the time deposit.</p>
<p>Pages: &#160;View CD Detail.</p>
<p class="Term">
<a name="Accrued_OID" id="Accrued_OID"></a>Accrued (Original Issue Discount)</p>
<p>Original Issue Discount Interest Accrued Year-to-Date. &#160;OID interest accrued in the current year.</p>
<p>Pages: &#160;View CD Detail.</p> 
 </body></html>

望ましい結果は次のようになります。

 <topic>
 <title>Arbitrary title</title>
 <body>
 <dl>
 <dlentry id="Accrued_Bonus_Interest">
 <dt>Accrued (Bonus Interest)</dt>
 <dd><p>Bonus Interest Accrued Cycle-to-Date. &#160;Amount of bonus interest that has accrued on the time deposit.</p>
 <p>Pages: View CD Detail</p></dd></dlentry>
 <dlentry id="Accrued_OID">
 <dt>Accrued (Original Issue Amount)</dt>
 <dd><p>Original Issue Discount Interest Accrued Year-to-Date. &#160;OID interest accrued in the current year.</p>
 <p>Pages: View CD Detail</p></dd>
 </dl>
 </body>
 </topic>

私はすでにこのほとんどを実現するスタイルシートを持っています。キーの適切な使用に関しては、(再び) 迷っているようです。次のスタイルシート:

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

<xsl:strip-space elements="*" />

<xsl:key name="kFollowing" match="*[not(p[@class='Term'])]" 
    use="generate-id(preceding::p[@class='Term'][1])"/>

<xsl:template match="/">
    <![CDATA[ 
    <!DOCTYPE topic PUBLIC "-//OASIS//DTD DITA Topic//EN" "topic.dtd">  ]]>
    <topic id="data_dictionary">
        <title>IBS Insight Data Dictionary</title>
        <body>
    <dl>
        <xsl:for-each select="/report/incident/file">
            <xsl:for-each select="document(.)/descendant::p[@class='Term']">
                <xsl:variable name="vFollowing" select="key('kFollowing', generate-id())"/> 
                <xsl:element name="dlentry">
                    <xsl:attribute name="id">
                        <xsl:value-of select="child::a/@id"/>
                    </xsl:attribute>
                    <dt><xsl:value-of select="."/></dt>
                    <dd><xsl:value-of select="$vFollowing"/>
                        <xsl:for-each select="following::*[$vFollowing]">
                            <xsl:apply-templates select="."/>
                        </xsl:for-each>
                    </dd>
                </xsl:element>
            </xsl:for-each>
      </xsl:for-each>                
    </dl></body></topic>
</xsl:template>

</xsl:stylesheet>

入力ファイルで定義されたファイルを正しくクロールし、dl正しいdlentryID とdt要素で を生成します。問題は、キーの混乱した実装がdd要素を組み立てる方法です。ここにある私のサンプル xml では明らかではありませんが、何が起こっているかというと、それぞれ<p class='Term'>が後続のすべての contnet を取得して、次の<dd>ように入力しているということです。

     <topic>
 <title>Arbitrary title</title>
 <body>
 <dl>
 <dlentry id="Accrued_Bonus_Interest">
 <dt>Accrued (Bonus Interest)</dt>
 <dd>Bonus Interest Accrued Cycle-to-Date. &#160;Amount of bonus interest that has accrued on the time deposit. Pages: View CD DetailAccrued (Original Issue Amount)Original Issue Discount Interest Accrued Year-to-Date. &#160;OID interest accrued in the current year.Pages: View CD Detail</dd></dlentry>
 <dlentry id="Accrued_OID">
 <dt>Accrued (Original Issue Amount)</dt>
 <dd><p>Original Issue Discount Interest Accrued Year-to-Date. &#160;OID interest accrued in the current year.</p>
 <p>Pages: View CD Detail</p></dd>
 </dl>
 </body>
 </topic>

各ファイルの最後の項目は正しくレンダリングされますが、これは処理するノードがこれ以上ないためです。私のコードの何かが、あまりにも多くのノードとキーを一致させています。

ご覧いただきありがとうございます。

4

1 に答える 1

2

キーの定義を少し変更します。

<xsl:key name="kFollowing"
    match="*[not(self::p[@class='Term'])][preceding-sibling::p[@class='Term']" 
    use="generate-id(preceding-sibling::p[@class='Term'][1])"/>

これは、それ自体ではない<p class="Term">が、ツリー内でそのような要素と同じレベルにある要素に一致し、これらを最も近い先行する「用語」でグループ化します。に続くコンテンツ<p class="Term">が単なるテキストノードである場合 (つまり、要素内にない場合) を許可したい場合は、代わりに

<xsl:key name="kFollowing"
    match="node()[not(self::p[@class='Term'])][preceding-sibling::p[@class='Term']" 
    use="generate-id(preceding-sibling::p[@class='Term'][1])"/>

次に、内側の for-each を単純化して、

        <xsl:for-each select="document(.)/descendant::p[@class='Term']">
            <dlentry id="{a/@id}">
                <dt><xsl:value-of select="."/></dt>
                <dd><xsl:copy-of select="key('kFollowing', generate-id())"/></dd>
            </dlentry>
        </xsl:for-each>
于 2012-11-19T22:42:06.557 に答える