1

我昨天发布了一个关于钥匙的问题,并得到了非常有用的回复。今天大部分时间我一直在研究这个特定文件集中的最后一个细节。在正确使用密钥方面,我一定缺少一些东西。

我有以下定义列表:

<dl>
<dlentry>
<dt>BLARG a</dt>
<dd>BLARG Definition b</dd>
</dlentry>
<dlentry>
<dt outputclass="values">Value c<ph> Value Description d</ph></dt>
<dd/>
</dlentry>
<dlentry>
<dt outputclass="values">Value e<ph> Value Description f</ph></dt>
<dd/>
</dlentry>
<dlentry>
<dt outputclass="values">Value g<ph> Value Description h</ph></dt>
<dd/>
</dlentry>
<dlentry>
<dt>BLARG2 i</dt>
<dd>BLARG2 Description j</dd>
</dlentry>
<dlentry>
<dt outputclass="values">Value k
<ph>Value description l</ph></dt>
<dd/>
</dlentry>
<dlentry>
<dt outputclass="values">Value m
    <ph>Value description n</ph></dt>
<dd/>
</dlentry>
<dlentry>
    <dt outputclass="values">Value o
    <ph>Value description p</ph></dt>
<dd/>
</dlentry>
<dlentry><dt>BLARG3 q</dt>
<dd>BLARG3 Definition r</dd></dlentry>
</dl>

这是我的转变(这不太奏效——我今天早些时候比这更接近,但设法让它变得更糟):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="kFollowing" match="dlentry[child::dt/@outputclass='values']" 
    use="generate-id(preceding-sibling::dlentry[not(child::dt/@outputclass='values')])"/>

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

<xsl:template match="dd[../following-sibling::dlentry[1]/dt[@outputclass='values']]">
    <xsl:variable name="vFollowing" select="key('kFollowing',generate-id(..))"/>
    <dd><xsl:value-of select="."/>
        <table>
            <tgroup cols="2">
                <colspec colnum="1" colname="col1" colwidth="*"/>
                <colspec colnum="2" colname="col2" colwidth="*"/>
                <tbody>
                    <xsl:for-each select="../following-sibling::dlentry[key('kFollowing',$vFollowing)]">
                        <row>
                            <entry colname="1">
                                <xsl:value-of select="./dt/text()"/>
                            </entry>
                            <entry colname="2">
                                <xsl:apply-templates select="./dt/ph/text()"></xsl:apply-templates>
                            </entry>
                        </row>
                    </xsl:for-each>
                </tbody>
            </tgroup>
        </table></dd>
</xsl:template>
</xsl:stylesheet>

我想要的输出:

<dl>
<dlentry>
    <dt>BLARG a</dt>
    <dd>BLARG Definition b
    <table>
        <tgroup cols="2">
            <colspec colnum="1" colname="col1" colwidth="*"/>
            <colspec colnum="2" colname="col2" colwidth="*"/>
            <tbody>
                <row>
                    <entry colname="1">Value c</entry>
                    <entry colname="2">Value Description d</entry>
                </row>
                <row>
                    <entry colname="1">Value e</entry>
                    <entry colname="2">Value Description f</entry>
                </row>
                <row>
                    <entry colname="1">Value g</entry>
                    <entry colname="2">Value Description h</entry>
                </row>
            </tbody>
        </tgroup>
    </table></dd>
</dlentry>
<dlentry>
    <dt>BLARG2 i</dt>
    <dd>BLARG2 Definition j
        <table>
            <tgroup cols="2">
                <colspec colnum="1" colname="col1" colwidth="*"/>
                <colspec colnum="2" colname="col2" colwidth="*"/>
                <tbody>
                    <row>
                        <entry colname="1">Value k</entry>
                        <entry colname="2">Value Description l</entry>
                    </row>
                    <row>
                        <entry colname="1">Value m</entry>
                        <entry colname="2">Value Description n</entry>
                    </row>
                    <row>
                        <entry colname="1">Value o</entry>
                        <entry colname="2">Value Description p</entry>
                    </row>
                </tbody>
            </tgroup>
        </table></dd>
</dlentry>
<dlentry><dt>BLARG3 q</dt>
    <dd>BLARG3 Definition r<dd></dlentry>
</dl>

分组规则(肖恩的编辑)

节点被分组在没有 dt[outputclass="values"] 子节点的节点上,并且所有后续的兄弟节点都具有 dt[outputclass="values"] 子节点。

节点的变换因此被分组。请注意,如果该组中只有一个成员(即没有 dlentry 具有 dt[outputclass="values"] 的 dt[outputclass="values"],那么示例输出文档中所示的表输出将被抑制。

4

1 回答 1

1

这个怎么样 ...

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

<xsl:key name="dl-group" match="dlentry[child::dt/@outputclass='values']" 
    use="generate-id( preceding-sibling::dlentry[ not( child::dt/@outputclass='values')][1])"/>

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

<xsl:template match="dlentry/dd">
 <xsl:variable name="head" select="generate-id(..)" />      
 <xsl:copy>
  <xsl:value-of select="." />
  <xsl:if test="count( key('dl-group',$head))"> 
   <xsl:text>&#x0A;</xsl:text>
   <table>
    <tgroup cols="2">
     <colspec colnum="1" colname="col1" colwidth="*"/>
     <colspec colnum="2" colname="col2" colwidth="*"/>
     <tbody>
      <xsl:for-each select="key('dl-group',$head)" >
       <row>
        <entry colname="1">
         <xsl:value-of select="normalize-space(./dt/text())" />
        </entry>
        <entry colname="2"><xsl:value-of select="./dt/ph/text()" /></entry>
       </row>
      </xsl:for-each>
     </tbody>
    </tgroup>
   </table>
  </xsl:if> 
 </xsl:copy>
</xsl:template>

<xsl:template match="dlentry[dt[@outputclass='values']]" />

</xsl:stylesheet>

解释

这只是键的直接应用。看起来你把事情复杂化了。也许您正在考虑 muenchian 分组。我们将头部 dd 节点的 id 放在一个变量中以节省重新计算。要生成行,我们只需遍历 key() 函数返回的节点集。

于 2012-06-15T04:03:49.593 回答