下面的链接描述了如何进行比较,但它比较了发生的次数和没有发生的站点将XSLT代码从2.0版转换为1.0版
<xsl:when test="count(key('networksAndIP', concat(w3:Name, '|', w3:IPAddress))) = $allStationsCount">Equal</xsl:when>
但实际上,我想比较表中的实际值,并显示比较状态。
结果将是列中存在的值的比较结果,而不是输入文件中存在的匹配记录的出现次数。我想更改以上代码行或替换以上代码行,因为存在多个相同的匹配记录,比较并给出错误的结果。
简而言之,计数(key('networksAndIP',concat(w3:Name,'|',w3:IPAddress)
下面的代码和我提供的链接完全相同,但我在输入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:Testa.txt</FilePath>
<Date>18.Apr.13</Date>
</SubDir>
<SubDir>
<FilePath>C:Testb.txt</FilePath>
<Date>18.Apr.13</Date>
</SubDir>
</Directory>
<Directory>
<InvokeBy>Exe</InvokeBy>
<SubDir>
<FilePath>C:Testa.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:Testa.txt</FilePath>
<Date>18.Apr.13</Date>
</SubDir>
<SubDir>
<FilePath>C:Testa.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:Testa.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:Testb.txt</td>
<td>UnEqual</td>
<td>18.Apr.13</td>
<td>NONE</td>
<td>NONE</td>
</tr>
</table>
它可以工作,但速度太慢。。。
<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>