Показать первые две позиции во вложенном дереве
Я новичок в 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, который создает таблицу для многих <c01>
s, <c02>
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 создается таблица, которая создает несколько столбцов, первые два из которых должны иметь <th>
s, которые тянут <container type>
(обычно "Коробка" и "Папка"). каждый <container type>
должен появляться только один раз за <c01>
, который он должен вытащить с первого раза <c02>
, Иногда есть <c02>
только с одним <container type>
иногда <c01>
с несколькими <c02>
с обоими <container type="box">
& <container type="folder">
,
Я перепробовал много вариантов position()=1
и используя <xsl:choose>
/<xsl:when>
почти все, что я могу придумать. Это либо всегда отображает <th>
за каждый случай <container type="box">
& <container type="folder">
или отображает <th>
каждый раз, когда есть два <container type>
s.
Есть идеи?
Обновление с фактическим (нежелательным) выводом
Меня попросили предоставить желаемый / фактический вывод XML. Это моя лучшая попытка передать фактический вывод HTML (так как я не могу скопировать / вставить его), игнорируя все <c01>
через </scopecontent>
(потому что я эту часть выяснил):
<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>
1 ответ
Ну, сначала я подумал, что это проблема группировки, требующая группировки мюнхенцев.
Но потом я посмотрел поближе и передумал. Вот как бы я это сделал:
<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>