XSLT多级过滤语法

时间:2016-05-09 02:01:51

标签: xml xslt

我想构建我的html报告,以便处理我的XML,如下所示。我正在努力使语法正确。 我可以在变量中获取外部cf_fixinpatch值,但不能在“select”中使用此值来进一步过滤部分。我知道我有什么记录......谢谢

输出Html

<html>
<cf_fixinpatch> <= loop through unique values
    write cf_fixinpatch header
   <section>    <= loop through unique values
    write section header
      <All records matching cf_fixinpatch and section values>  <= loop
       Write out various aspects of the Result node
   </section>
<cf_fixinpatch>
</html>

输入XML

<DocumentElement>
  <Results> <= many repeat nodes
    <bug_id>64252</bug_id>
    <name>SCADA</name>
    <short_desc>[FUNCTIONALITY]: Server name is not correct in SOE System Message</short_desc>
    <bug_status>VERIFIED</bug_status>
    <resolution>FIXED</resolution>
    <bug_severity>normal</bug_severity>
    <section>Alarms</section>
    <release_title>Some SOE items that reference an alarm server do not use its proper name</release_title>
    <release_notes>Such events now use "ClusterName_ServerName" when referencing alarm servers.</release_notes>
    <cf_fixinpatch>v7.50 SP1 Patch 5</cf_fixinpatch>
  </Results>
  ...
</DocumentElement>

注意:使用不支持2.0的Windows msxl(如果太难,可以移动到2.0),我可以做类似的事情

<xsl:variable name="unique-list" select="/DocumentElement/Results[not(cf_fixinpatch=following::Results/cf_fixinpatch)]" />
 <xsl:for-each select="$unique-list">
 <xsl:variable name="current_patch" select="cf_fixinpatch" />
   <!-- but don't know how to use this in the next loop -->
 -----------------
<xsl:for-each select="/DocumentElement/Results">
<xsl:if test="not(section = preceding-sibling::section)"> <= cant get to work, if worked i can win or
 <xsl:if test="cf_fixinpatch != Results[position()-1]/cf_fixinpatch">

PM 09/05反馈 - 我找到了一个解决方案但很难做到这一点,所以我提供了一些反馈

    <xsl:for-each select="/DocumentElement/Results">

        <xsl:variable name="thePatch" select="preceding-sibling::Results[1]/cf_fixinpatch"></xsl:variable>
        <xsl:if test="($Patches = 'true') and (position() = 1 or cf_fixinpatch != $thePatch)">
            <!-- Write out the Patch Level -->
             <h4 style="color:#d82553">
                <a>
                  <xsl:value-of select="cf_fixinpatch" />
                </a>
            </h4>
        </xsl:if>       

        <xsl:variable name="theSection" select="preceding-sibling::Results[1]/section"></xsl:variable>

        <xsl:if test="(position() = 1) or (section != $theSection)">
             <!-- Write out the Section Information -->
            <h4 style="color:#C75B12;text-index:40px">
                <a>
                <xsl:value-of select="section" />
                </a>
            </h4>
        </xsl:if>

        <!-- Then record info written out -->

1 个答案:

答案 0 :(得分:1)

您似乎首先按Resultscf_fixinpatch元素进行分组,然后对同一个修补程序中的所有元素按section元素进行分组。这意味着您正在进行两次分组。要按cf_fixinpatch分组,您需要此密钥

<xsl:key name="results_by_patch" match="Results" use="cf_fixinpatch" />

但是要对给定组中所有section元素的Results值进行分组(而不是文档中的所有Results),您需要一个连接键

<xsl:key name="results_by_patch_and_section" match="Results" use="concat(cf_fixinpatch, '|', section)" />

试试这个将很多Muenchian分组嵌入另一个内部的XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />

  <xsl:key name="results_by_patch" match="Results" use="cf_fixinpatch" />
  <xsl:key name="results_by_patch_and_section" match="Results" use="concat(cf_fixinpatch, '|', section)" />

  <xsl:template match="DocumentElement">
    <html>
      <body>
        <xsl:for-each select="Results[generate-id() = generate-id(key('results_by_patch', cf_fixinpatch)[1])]">
          <h1 style="color:#d82553">
            <xsl:value-of select="cf_fixinpatch" />
          </h1>
          <xsl:for-each select="key('results_by_patch', cf_fixinpatch)[generate-id() = generate-id(key('results_by_patch_and_section', concat(cf_fixinpatch, '|', section))[1])]">
            <h2 style="color:#C75B12;text-index:40px">
              <xsl:value-of select="section" />
            </h2>
            <xsl:apply-templates select="key('results_by_patch_and_section', concat(cf_fixinpatch, '|', section))" />
          </xsl:for-each>
        </xsl:for-each>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="Results">
    <div>
      <xsl:value-of select="bug_id" />
    </div>
  </xsl:template>
</xsl:stylesheet>