使用 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>&#xA0;</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>&#xA0;</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>

呈现为: