使用 children 的值构建 table,其 parents 只有具有特定属性值的兄弟姐妹
Building a table with the values of children whose parents only have siblings with particular attribute values
我为所有的代码道歉,但我无法在不混淆问题清晰度的情况下删除更多代码。
假设我有这个 XML:
<Dataset>
<Rec RN="FOO">
<Fld FN="ID">ID_1</Fld>
<Fld FN="OPT">0</Fld>
<Fld FN="DESCRIPTION">DESCRIPTION_1</Fld>
</Rec>
<Rec RN="BAR" RC="3">
<Fld FN="ID">ID_2</Fld>
<Fld FN="TYPE">TYPE_1</Fld>
</Rec>
<Rec RN="BAR">
<Fld FN="ID">ID_3</Fld>
<Fld FN="TYPE">TYPE_2</Fld>
</Rec>
<Rec RN="FOO">
<Fld FN="ID">ID_4</Fld>
<Fld FN="OPT">1</Fld>
<Fld FN="DESCRIPTION">DESCRIPTION_2</Fld>
</Rec>
<Rec RN="BAR" RC="3">
<Fld FN="ID">ID_5</Fld>
<Fld FN="TYPE">TYPE_4</Fld>
</Rec>
<Rec RN="BAR">
<Fld FN="ID">ID_6</Fld>
<Fld FN="TYPE">TYPE_5</Fld>
</Rec>
<Rec RN="SPAM">
<Fld FN="CLASS">CLASS_1</Fld>
</Rec>
</Dataset>
以及以下 XSLT:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Dataset">
<html>
<head>
<link rel="stylesheet" type="text/css" href="On-line Styles.css"/>
</head>
<body>
<p class="subheading">
Commands
</p>
<p>
<xsl:choose>
<xsl:when test="Rec[@RN='FOO']">
<xsl:apply-templates select="Rec[@RN='FOO']"/>
</xsl:when>
<xsl:otherwise>
None
</xsl:otherwise>
</xsl:choose>
</p>
</body>
</html>
</xsl:template>
<xsl:template match="Rec[@RN='FOO']">
<xsl:for-each select=".">
<xsl:value-of select="Fld[@FN='ID']"/>
<xsl:if test="Fld[@FN='OPT'] = 1">
(Optional)
</xsl:if>
-
<xsl:value-of select="Fld[@FN='DESCRIPTION']"/>
<p>
<xsl:choose>
<xsl:when test="../Rec[@RN='FOO']">
<table style="border-collapse: separate;" cellspacing="4" border="2"
bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<xsl:for-each select="../Rec[@RN='BAR']">
<xsl:if test="preceding-sibling::Rec/@RN='FOO'">
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">
<xsl:choose>
<xsl:when test="Fld[@FN='ID']">
<xsl:value-of select="Fld[@FN='ID']"/>
</xsl:when>
<xsl:otherwise>
<td> </td>
</xsl:otherwise>
</xsl:choose>
</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">
<xsl:choose>
<xsl:when test="Fld[@FN='TYPE']">
<xsl:value-of select="Fld[@FN='TYPE']"/>
</xsl:when>
<xsl:otherwise>
<td> </td>
</xsl:otherwise>
</xsl:choose>
</p>
</td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:when>
</xsl:choose>
</p>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我得到 table 的以下输出:
Table 1
<table style="border-collapse: separate;" cellspacing="4" border="2" bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_2</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_1</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_3</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_2</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_5</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_4</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_6</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_5</p>
</td>
</tr>
</table>
Table 2
<table style="border-collapse: separate;" cellspacing="4" border="2" bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_2</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_1</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_3</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_2</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_5</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_4</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_6</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_5</p>
</td>
</tr>
</table>
我需要的是每个 table 仅显示 <Rec RN="FOO">
之后和下一个 <Rec RN="FOO">
之前的 <Rec RN="BAR">
的 ID 和 TYPE 文本值或 <Rec>
与另一个 @RN 值。 <Rec RN="FOO">
后面可以有 1 到 n 个 <Rec RN="BAR">
。以下示例显示了我需要的输出:
Table 1
<table style="border-collapse: separate;" cellspacing="4" border="2" bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_2</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_1</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_3</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_2</p>
</td>
</tr>
</table>
Table 2
<table style="border-collapse: separate;" cellspacing="4" border="2" bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_5</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_4</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_6</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_5</p>
</td>
</tr>
</table>
如果我理解正确(一点也不确定),你想做这样的事情:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="rows" match="Rec[@RN='BAR']" use="generate-id(preceding-sibling::Rec[@RN='FOO'][1])" />
<xsl:template match="/Dataset">
<html>
<body>
<xsl:apply-templates select="Rec[@RN='FOO']"/>
</body>
</html>
</xsl:template>
<xsl:template match="Rec[@RN='FOO']">
<table border="1">
<tr>
<th>ID</th>
<th>TYPE</th>
</tr>
<xsl:apply-templates select="key('rows', generate-id())"/>
</table>
<p/>
</xsl:template>
<xsl:template match="Rec[@RN='BAR']">
<tr>
<td>
<xsl:value-of select="Fld[@FN='ID']"/>
</td>
<td>
<xsl:value-of select="Fld[@FN='TYPE']"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
应用于您的示例输入,结果将是:
<html>
<body>
<table border="1">
<tr>
<th>ID</th>
<th>TYPE</th>
</tr>
<tr>
<td>ID_2</td>
<td>TYPE_1</td>
</tr>
<tr>
<td>ID_3</td>
<td>TYPE_2</td>
</tr>
</table>
<p></p>
<table border="1">
<tr>
<th>ID</th>
<th>TYPE</th>
</tr>
<tr>
<td>ID_5</td>
<td>TYPE_4</td>
</tr>
<tr>
<td>ID_6</td>
<td>TYPE_5</td>
</tr>
</table>
<p></p>
</body>
</html>
呈现为:
我为所有的代码道歉,但我无法在不混淆问题清晰度的情况下删除更多代码。
假设我有这个 XML:
<Dataset>
<Rec RN="FOO">
<Fld FN="ID">ID_1</Fld>
<Fld FN="OPT">0</Fld>
<Fld FN="DESCRIPTION">DESCRIPTION_1</Fld>
</Rec>
<Rec RN="BAR" RC="3">
<Fld FN="ID">ID_2</Fld>
<Fld FN="TYPE">TYPE_1</Fld>
</Rec>
<Rec RN="BAR">
<Fld FN="ID">ID_3</Fld>
<Fld FN="TYPE">TYPE_2</Fld>
</Rec>
<Rec RN="FOO">
<Fld FN="ID">ID_4</Fld>
<Fld FN="OPT">1</Fld>
<Fld FN="DESCRIPTION">DESCRIPTION_2</Fld>
</Rec>
<Rec RN="BAR" RC="3">
<Fld FN="ID">ID_5</Fld>
<Fld FN="TYPE">TYPE_4</Fld>
</Rec>
<Rec RN="BAR">
<Fld FN="ID">ID_6</Fld>
<Fld FN="TYPE">TYPE_5</Fld>
</Rec>
<Rec RN="SPAM">
<Fld FN="CLASS">CLASS_1</Fld>
</Rec>
</Dataset>
以及以下 XSLT:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="Dataset">
<html>
<head>
<link rel="stylesheet" type="text/css" href="On-line Styles.css"/>
</head>
<body>
<p class="subheading">
Commands
</p>
<p>
<xsl:choose>
<xsl:when test="Rec[@RN='FOO']">
<xsl:apply-templates select="Rec[@RN='FOO']"/>
</xsl:when>
<xsl:otherwise>
None
</xsl:otherwise>
</xsl:choose>
</p>
</body>
</html>
</xsl:template>
<xsl:template match="Rec[@RN='FOO']">
<xsl:for-each select=".">
<xsl:value-of select="Fld[@FN='ID']"/>
<xsl:if test="Fld[@FN='OPT'] = 1">
(Optional)
</xsl:if>
-
<xsl:value-of select="Fld[@FN='DESCRIPTION']"/>
<p>
<xsl:choose>
<xsl:when test="../Rec[@RN='FOO']">
<table style="border-collapse: separate;" cellspacing="4" border="2"
bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<xsl:for-each select="../Rec[@RN='BAR']">
<xsl:if test="preceding-sibling::Rec/@RN='FOO'">
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">
<xsl:choose>
<xsl:when test="Fld[@FN='ID']">
<xsl:value-of select="Fld[@FN='ID']"/>
</xsl:when>
<xsl:otherwise>
<td> </td>
</xsl:otherwise>
</xsl:choose>
</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">
<xsl:choose>
<xsl:when test="Fld[@FN='TYPE']">
<xsl:value-of select="Fld[@FN='TYPE']"/>
</xsl:when>
<xsl:otherwise>
<td> </td>
</xsl:otherwise>
</xsl:choose>
</p>
</td>
</tr>
</xsl:if>
</xsl:for-each>
</table>
</xsl:when>
</xsl:choose>
</p>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我得到 table 的以下输出:
Table 1
<table style="border-collapse: separate;" cellspacing="4" border="2" bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_2</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_1</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_3</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_2</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_5</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_4</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_6</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_5</p>
</td>
</tr>
</table>
Table 2
<table style="border-collapse: separate;" cellspacing="4" border="2" bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_2</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_1</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_3</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_2</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_5</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_4</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_6</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_5</p>
</td>
</tr>
</table>
我需要的是每个 table 仅显示 <Rec RN="FOO">
之后和下一个 <Rec RN="FOO">
之前的 <Rec RN="BAR">
的 ID 和 TYPE 文本值或 <Rec>
与另一个 @RN 值。 <Rec RN="FOO">
后面可以有 1 到 n 个 <Rec RN="BAR">
。以下示例显示了我需要的输出:
Table 1
<table style="border-collapse: separate;" cellspacing="4" border="2" bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_2</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_1</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_3</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_2</p>
</td>
</tr>
</table>
Table 2
<table style="border-collapse: separate;" cellspacing="4" border="2" bordercolorlight="#c0c0c0" bordercolordark="#c0c0c0">
<tr bgcolor="#C0C0C0">
<td style="width: 35%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">ID</span>
</p>
</td>
<td style="width: 45%; padding: 6px;" valign="top">
<p class="Tableheader" style="margin-bottom: 0;">
<span style="font-weight: bold;">TYPE</span>
</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_5</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_4</p>
</td>
</tr>
<tr>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">ID_6</p>
</td>
<td style="padding: 6px;" valign="top">
<p style="margin-bottom: 0;">TYPE_5</p>
</td>
</tr>
</table>
如果我理解正确(一点也不确定),你想做这样的事情:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="rows" match="Rec[@RN='BAR']" use="generate-id(preceding-sibling::Rec[@RN='FOO'][1])" />
<xsl:template match="/Dataset">
<html>
<body>
<xsl:apply-templates select="Rec[@RN='FOO']"/>
</body>
</html>
</xsl:template>
<xsl:template match="Rec[@RN='FOO']">
<table border="1">
<tr>
<th>ID</th>
<th>TYPE</th>
</tr>
<xsl:apply-templates select="key('rows', generate-id())"/>
</table>
<p/>
</xsl:template>
<xsl:template match="Rec[@RN='BAR']">
<tr>
<td>
<xsl:value-of select="Fld[@FN='ID']"/>
</td>
<td>
<xsl:value-of select="Fld[@FN='TYPE']"/>
</td>
</tr>
</xsl:template>
</xsl:stylesheet>
应用于您的示例输入,结果将是:
<html>
<body>
<table border="1">
<tr>
<th>ID</th>
<th>TYPE</th>
</tr>
<tr>
<td>ID_2</td>
<td>TYPE_1</td>
</tr>
<tr>
<td>ID_3</td>
<td>TYPE_2</td>
</tr>
</table>
<p></p>
<table border="1">
<tr>
<th>ID</th>
<th>TYPE</th>
</tr>
<tr>
<td>ID_5</td>
<td>TYPE_4</td>
</tr>
<tr>
<td>ID_6</td>
<td>TYPE_5</td>
</tr>
</table>
<p></p>
</body>
</html>
呈现为: