显示嵌套树中的前两个位置

Posted

技术标签:

【中文标题】显示嵌套树中的前两个位置【英文标题】:Display first two positions in nested tree 【发布时间】:2012-09-19 18:32:24 【问题描述】:

我是 XSL 的新手,边走边学。我目前正在为本地创建的 XML 编辑第三方样式表,其中一部分如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl">

<c01>
    <did>
        <unittitle>Annual Reports</unittitle>
        <physdesc>19 folders</physdesc>                                   
    </did>
    <scopecontent>
        <p>Annual reports...</p>
    </scopecontent>
    <c02>
        <did>
            <container type="box">1</container>
            <container type="folder">1</container>
            <unittitle>1839-40, 1846 (SPP); 1852 (BPA); 1854 (SPP)</unittitle>
        </did>
    </c02>
    <c02>
         <did>
            <container type="folder">2</container>
            <unittitle>1869, 1872 (BPA); 1873 (IAS)</unittitle>
         </did>
    </c02>

<c01>
     <did>
         <unittitle>Bulletins</unittitle>
         <physdesc>2 folders</physdesc>
     </did>
     <scopecontent>
         <p>Bulletins...</p>
     </scopecontent>
     <c02>
         <did>
             <container type="box">1</container>
             <container type="folder">21</container>
             <unittitle>Bulletins 1945-46</unittitle>
         </did>
     </c02>
     <c02>
         <did>
         <container type="box">2</container>
         <container type="folder">1</container>
         <unittitle>Bulletins 1946-51</unittitle>
         </did>
     </c02>
</c01>

使用一些 XSL 为许多 &lt;c01&gt;s、&lt;c02&gt;s 等创建一个表,部分看起来像这样:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="ISO-8859-1" doctype-public="-//W3C//DTD HTML 4.0 Transitional//EN"/>

<xsl:template match="c02/did">
<tr>    
    <xsl:choose>
        <xsl:when test="ancestor::c01/descendant::c02/did/container">
            <xsl:if test="position()=1">
                <th><xsl:value-of select="container[1]/@type"/></th>
                <th><xsl:value-of select="container[2]/@type"/></th>
            </xsl:if>
        </xsl:when>
        <xsl:otherwise></xsl:otherwise>
    </xsl:choose>
</tr>
</xsl:template>

在创建多个列的 XSL 中的此模板之前创建一个表,其中前两个具有拉动&lt;container type&gt;&lt;th&gt;s(通常是“Box”和“Folder”)。每个&lt;container type&gt; 每个&lt;c01&gt; 应该只出现一次,它应该从第一个&lt;c02&gt; 中提取。有时&lt;c02&gt;s 只有一个&lt;container type&gt;,有时&lt;c01&gt;s 有多个&lt;c02&gt;s,同时有&lt;container type="box"&gt;&lt;container type="folder"&gt;

我尝试了position()=1&lt;xsl:choose&gt;/&lt;xsl:when&gt; 的许多变体,几乎所有我能想到的。它要么总是为&lt;container type="box"&gt;&lt;container type="folder"&gt; 的每个实例显示&lt;th&gt;,要么在每次有两个&lt;container type&gt;s 时显示&lt;th&gt;s。

有什么想法吗?

使用实际(不需要的)输出进行更新 我被要求提供一些期望/实际的 XML 输出。这是我传达实际 HTML 输出的最佳尝试(因为我无法复制/粘贴它),忽略从 &lt;c01&gt;&lt;/scopecontent&gt; 的所有内容(因为我已经弄清楚了那部分):

<tr>
<th>Box</th>
<th>Folder</th>
</tr>

<tr>
<td>1</td>
<td>1</td>
<td>1839-40, 1846 (SPP); 1852 (BPA); 1854 (SPP)</td>
</tr>

<tr>
<th>Folder</th>
</tr>

<tr>
<td></td>
<td>2</td>
<td>1869, 1872 (BPA); 1873 (IAS)</td>
</tr>

...

<tr>
<th>Box</th>
<th>Folder</th>
</tr>

<tr>
<td>1</td>
<td>21</td>
<td>Bulletins 1945-46</td>
</tr>

<tr>
<th>Box</th>
<th>Folder</th>
</tr>

<tr>
<td>2</td>
<td>1</td>
<td>Bulletins 1946-51</td>
</tr>

期望的输出

<tr>
<th>Box</th>
<th>Folder</th>
</tr>

<tr>
<td>1</td>
<td>1</td>
<td>1839-40, 1846 (SPP); 1852 (BPA); 1854 (SPP)</td>
</tr>

<tr>
<td></td>
<td>2</td>
<td>1869, 1872 (BPA); 1873 (IAS)</td>
</tr>

...

<tr>
<th>Box</th>
<th>Folder</th>
</tr>

<tr>
<td>1</td>
<td>21</td>
<td>Bulletins 1945-46</td>
</tr>

<tr>
<td>2</td>
<td>1</td>
<td>Bulletins 1946-51</td>
</tr>

【问题讨论】:

散文很好地解释了需要什么,但并不完全清楚。您可以发布所需的 XML 输出来演示您想要的内容吗?发布实际的 XML 输出来演示现有代码出了什么问题会更有帮助。 @LarsH 更新了实际和期望的输出。希望对您有所帮助! 是的,非常有帮助!请查看我发布的解决方案。 【参考方案1】:

好吧,我起初以为这是一个需要 Muenchian grouping 的分组问题。

但后来我仔细观察并改变了主意。以下是我的做法:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html" encoding="ISO-8859-1"
    doctype-public="-//W3C//DTD HTML 4.0 Transitional//EN" />

  <xsl:template match="c01">
    <xsl:variable name="c01ID" select="generate-id()" />
    <tr>
      <xsl:for-each select="c02[1]//container">
        <th>
          <xsl:value-of select="@type" />
        </th>
      </xsl:for-each>
    </tr>
    <xsl:apply-templates select="c02" />
  </xsl:template>

  <xsl:template match="c02/did">
    <tr>
      <xsl:variable name="contextDid" select="." />
      <xsl:for-each select="ancestor::c01/c02[1]//container/@type">
        <xsl:variable name="currentType" select="." />

        <td>
          <xsl:value-of
            select="$contextDid/container[@type = $currentType]/text()" />
        </td>
      </xsl:for-each>

      <xsl:for-each select="unittitle">
        <td>
          <xsl:value-of select="." />
        </td>
      </xsl:for-each>
    </tr>
  </xsl:template>
</xsl:stylesheet>

针对以下示例输入运行时:

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl"?>

<root>
  <c01>
    <did>
      <unittitle>Annual Reports</unittitle>
      <physdesc>19 folders</physdesc>
    </did>
    <scopecontent>
      <p>Annual reports...</p>
    </scopecontent>
    <c02>
      <did>
        <container type="box">1</container>
        <container type="folder">1</container>
        <unittitle>1839-40, 1846 (SPP); 1852 (BPA); 1854 (SPP)</unittitle>
      </did>
    </c02>
    <c02>
      <did>
        <container type="folder">2</container>
        <unittitle>1869, 1872 (BPA); 1873 (IAS)</unittitle>
      </did>
    </c02>
  </c01>

  <c01>
    <did>
      <unittitle>Bulletins</unittitle>
      <physdesc>2 folders</physdesc>
    </did>
    <scopecontent>
      <p>Bulletins...</p>
    </scopecontent>
    <c02>
      <did>
        <container type="box">1</container>
        <container type="folder">21</container>
        <unittitle>Bulletins 1945-46</unittitle>
      </did>
    </c02>
    <c02>
      <did>
        <container type="box">2</container>
        <container type="folder">1</container>
        <unittitle>Bulletins 1946-51</unittitle>
      </did>
    </c02>
  </c01>
</root>

它产生所需的输出:

<tr>
   <th>box</th>
   <th>folder</th>
</tr>

<tr>
   <td>1</td>
   <td>1</td>
   <td>1839-40, 1846 (SPP); 1852 (BPA); 1854 (SPP)</td>
</tr>    

<tr>
   <td></td>
   <td>2</td>
   <td>1869, 1872 (BPA); 1873 (IAS)</td>
</tr>


<tr>
   <th>box</th>
   <th>folder</th>
</tr>

<tr>
   <td>1</td>
   <td>21</td>
   <td>Bulletins 1945-46</td>
</tr>

<tr>
   <td>2</td>
   <td>1</td>
   <td>Bulletins 1946-51</td>
</tr>

【讨论】:

注意我假设每个 c01 元素的第一个 c02 子元素包含所有容器类型,并且每个容器类型只包含一次,如您的示例输入中所示。如果这不一定正确,请澄清问题。

以上是关于显示嵌套树中的前两个位置的主要内容,如果未能解决你的问题,请参考以下文章

设置层的显示效果的选项是

在深度嵌套的视觉树中拖放装饰器

Angular Material - 扁平树和嵌套树之间的区别

R语言使用treemap包中的treemap函数可视化treemap图:treemap将分层数据显示为一组嵌套矩形自定义设置标签颜色标签背景色标签大小字体格式边界线条粗细标签位置等

android中ScrollView嵌套ListView或GridView显示位置问题

Android - 嵌套 LinearLayout 中的按钮不显示