如何比较列值结果和显示状态?

时间:2014-01-16 06:18:01

标签: xslt xslt-1.0

以下链接描述了如何比较,但它比较了发生次数与没有站点 convert XSLT code from version 2.0 to 1.0

<xsl:when test="count(key('networksAndIP', concat(w3:Name, '|', w3:IPAddress))) = $allStationsCount">Equal</xsl:when>

但实际上我想比较表中存在的实际值并显示比较状态。

结果将比较存在于输入文件中存在的匹配记录的列中存在的值的结果。我想更改上面的代码行或替换上面的代码行,比较并给出不正确的结果,存在多个相同的匹配记录。

简而言之 count(密钥('networksAndIP',concat(w3:名称,'|',w3:IPAddress)))给出的总数不是10或5取决于数字记录但总站数只有3($ allStationsCount),因此它永远不会显示正确的结果

下面的代码与我提供的链接完全相同,但我在输入xml文件中做了一些更改。

输入XML

<?xml version="1.0" encoding="utf-8"?>
    <OperatorStationCollection xmlns="http://www.w3.org" >
    <OperatorStation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <Name>OS001</Name>
        <Nodes>
          <DataNodeBase xsi:type="Adaptor">
            <Family>NetworkSettings</Family>
            <Name>Network A</Name>  
            <IPAddress>111.11.11.1</IPAddress>        
          </DataNodeBase>          
          </Nodes>   
      </OperatorStation>      
    <OperatorStation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <Name>OS002</Name>
      <Nodes>
        <DataNodeBase xsi:type="Adaptor">
          <Family>NetworkSettings</Family>
          <Name>Network A</Name>
          <IPAddress>111.11.11.1</IPAddress>
        </DataNodeBase>        
      </Nodes>
    </OperatorStation>
      <OperatorStation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <Name>OS003</Name>
        <Nodes>
          <DataNodeBase xsi:type="Adaptor">
            <Family>NetworkSettings</Family>
            <Name>Network A</Name>
            <IPAddress>111.11.11.1</IPAddress>
          </DataNodeBase>
          <DataNodeBase xsi:type="Adaptor">
            <Family>NetworkSettings</Family>
            <Name>Network A</Name>
            <IPAddress>111.11.11.1</IPAddress>
          </DataNodeBase>          
        </Nodes>
      </OperatorStation>
    </OperatorStationCollection>

XSLT代码

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

   <xsl:key name="networks" match="w3:DataNodeBase" use="w3:Name"/>
   <xsl:key name="networksAndIP" match="w3:DataNodeBase" use="concat(w3:Name, '|', w3:IPAddress)"/>

   <xsl:variable name="allStations" select="//w3:OperatorStation"/>
   <xsl:variable name="allStationsCount" select="count($allStations)"/>

   <xsl:template match="/">
      <table><!-- Header row - two fixed columns plus one per station name -->
         <tr>
            <td>Name</td>
            <td>Status</td>
            <xsl:for-each select="$allStations">
               <td>
                  <xsl:value-of select="w3:Name"/>
               </td>
            </xsl:for-each>
         </tr>
         <xsl:apply-templates select="//w3:DataNodeBase[generate-id() = generate-id(key('networks', w3:Name)[1])]"/>
      </table>
   </xsl:template>

   <xsl:template match="w3:DataNodeBase">
      <tr>
         <td>
            <xsl:value-of select="w3:Name"/>
         </td>
         <td>
            <xsl:choose>
               <xsl:when test="count(key('networksAndIP', concat(w3:Name, '|', w3:IPAddress))) = $allStationsCount">Equal</xsl:when>
               <xsl:otherwise>Unequal</xsl:otherwise>
            </xsl:choose>
         </td>
         <xsl:variable name="network" select="w3:Name"/>
         <xsl:for-each select="$allStations">
            <td>
               <xsl:value-of select="key('networks', $network)[../../w3:Name=current()/w3:Name]/w3:IPAddress"/>
            </td>
         </xsl:for-each>
      </tr>
   </xsl:template>
</xsl:stylesheet>

输出:输出显示状态是不等的,即使所有记录都相等,但是没有出现多于站点的数据。

   <table xmlns:w3="http://www.w3.org">
   <tr>
      <td>Name</td>
      <td>Status</td>
      <td>OS001</td>
      <td>OS002</td>
      <td>OS003</td>
   </tr>
   <tr>
      <td>Network A</td>
      <td>Unequal</td>
      <td>111.11.11.1</td>
      <td>111.11.11.1</td>
      <td>111.11.11.1</td>
   </tr>
</table>

具有相同输入文件的预期输出。

<table xmlns:w3="http://www.w3.org">
   <tr>
      <td>Name</td>
      <td>Status</td>
      <td>OS001</td>
      <td>OS002</td>
      <td>OS003</td>
   </tr>
   <tr>
      <td>Network A</td>
      <td>Equal</td>
      <td>111.11.11.1</td>
      <td>111.11.11.1</td>
      <td>111.11.11.1</td>
   </tr>
</table>

另一个输入示例file2.xml

<?xml version="1.0" encoding="utf-8"?>
    <Base>
        <Directory>
          <InvokeBy>Registry</InvokeBy>          
          <SubDir>
            <FilePath>C:\Test\a.txt</FilePath>
            <Date>18.Apr.13</Date>    
          </SubDir>  
          <SubDir>
            <FilePath>C:\Test\b.txt</FilePath>
            <Date>18.Apr.13</Date>    
          </SubDir>
        </Directory>
        <Directory>
        <InvokeBy>Exe</InvokeBy>
          <SubDir>            
            <FilePath>C:\Test\a.txt</FilePath>
            <Date>18.Apr.13</Date>      
          </SubDir>          
        </Directory>
        <Directory>
        <InvokeBy>Script</InvokeBy>
        //below code have two SubDir Nodes having same file path, but it should consider any one and skip all remaining otherwise it will give incorrect count record. 
          <SubDir>            
            <FilePath>C:\Test\a.txt</FilePath>
            <Date>18.Apr.13</Date>      
          </SubDir> 
          <SubDir>
            <FilePath>C:\Test\a.txt</FilePath>
            <Date>18.Apr.13</Date>    
          </SubDir> 
        </Directory>
</Base>

File2.xml的预期O / P

<table xmlns:w3="http://www.w3.org">
   <tr>
      <td>File</td>
      <td>Compared Status</td>
      <td>Registry</td>
      <td>Exe</td>
      <td>Script</td>
   </tr>
   <tr>
      <td>C:\Test\a.txt</td> 
      <td>Equal</td>          //Here it should show Equal only when all invoke type have same file date, but it will be unequal if you consider code for count of maching occurrence.  by the code line.I have added at top
      <td>18.Apr.13</td>
      <td>18.Apr.13</td>
      <td>18.Apr.13</td>
   </tr>
    <tr>
      <td>C:\Test\b.txt</td>
      <td>UnEqual</td>
      <td>18.Apr.13</td>
      <td>NONE</td>
      <td>NONE</td>
   </tr>
</table>

1 个答案:

答案 0 :(得分:0)

它有效,但速度太慢......

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
     xmlns:w3="http://www.w3.org" exclude-result-prefixes="w3">

  <!-- grouping key to pull out all the DataNodeBase elements with a
       particular name -->
  <xsl:key name="dnbByName" match="w3:DataNodeBase" use="w3:Name" />

  <xsl:template match="/">
    <xsl:variable name="allStations"
                  select="/w3:OperatorStationCollection/w3:OperatorStation" />
    <table>
      <tr>
        <td>Name</td><td>Status</td>
        <xsl:for-each select="$allStations">
          <td><xsl:value-of select="w3:Name" /></td>
        </xsl:for-each>
      </tr>
      <!-- Muenchian grouping - for-each over a set consisting of just one
           DataNodeBase per network name "group" -->
      <xsl:for-each select="$allStations/w3:Nodes/w3:DataNodeBase[
            generate-id() = generate-id(key('dnbByName', w3:Name)[1])]">
        <xsl:variable name="current-group" select="key('dnbByName', w3:Name)" />
        <xsl:variable name="current-grouping-key" select="w3:Name" />
        <tr>
          <td><xsl:value-of select="$current-grouping-key" /></td>
          <td>
            <xsl:choose>
              <!-- "Equal" if all stations have a value for this network name,
                   and all these values are the same (it is not the case that
                   any of the values is different from that of the first
                   station) -->
              <xsl:when test="$current-group/w3:IPAddress = $current-group[1]/w3:IPAddress">
                <xsl:text>Equal</xsl:text>
              </xsl:when>
              <xsl:otherwise>
                <xsl:text>Unequal</xsl:text>
              </xsl:otherwise>
            </xsl:choose>
          </td>
          <!-- remaining columns, one per station -->
          <xsl:for-each select="$allStations">
            <td>
              <!-- check whether this station has an address for this network -->
              <xsl:variable name="address" select="w3:Nodes/w3:DataNodeBase[
                      w3:Name = $current-grouping-key]/w3:IPAddress" />
              <xsl:choose>
                <xsl:when test="$address">
                  <xsl:value-of select="$address" />
                </xsl:when>
                <xsl:otherwise>None</xsl:otherwise>
              </xsl:choose>
            </td>
          </xsl:for-each>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>
</xsl:stylesheet>