下面的XSLT代码给出了父节点比较结果的结果。我正在寻找子节点比较结果,预期结果如下所示。 描述:XSLT代码给出了父节点(网络A,网络B等),我希望子节点(网络AA,网络AB等)比较结果。我建议你检查输入xml文件和预期输出,以便轻松了解我的要求。请参考链接convert XSLT code from version 2.0 to 1.0
输入XML文件:
<?xml version="1.0" encoding="utf-8"?>
<OperatorStationCollection >
<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>
<ChildNodes>
<DataNodeChild xsi:type="SubResult">
<Family>NetworkSettings</Family>
<Name>Network AA</Name>
<IPAddress>111.11.11.12</IPAddress>
</DataNodeChild>
<DataNodeChild xsi:type="SubResult">
<Family>NetworkSettings</Family>
<Name>Network AB</Name>
<IPAddress>111.11.11.13</IPAddress>
</DataNodeChild>
</ChildNodes>
</DataNodeBase>
<DataNodeBase xsi:type="Adaptor">
<Family>NetworkSettings</Family>
<Name>Network B</Name>
<IPAddress>111.22.11.1</IPAddress>
<ChildNodes>
<DataNodeChild xsi:type="SubResult">
<Family>NetworkSettings</Family>
<Name>Network BA</Name>
<IPAddress>111.11.11.21</IPAddress>
</DataNodeChild>
<DataNodeChild xsi:type="SubResult">
<Family>NetworkSettings</Family>
<Name>Network BB</Name>
<IPAddress>111.11.11.31</IPAddress>
</DataNodeChild>
</ChildNodes>
</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>
<ChildNodes>
<DataNodeChild xsi:type="SubResult">
<Family>NetworkSettings</Family>
<Name>Network AA</Name>
<IPAddress>111.11.11.12</IPAddress>
</DataNodeChild>
<DataNodeChild xsi:type="SubResult">
<Family>NetworkSettings</Family>
<Name>Network AB</Name>
<IPAddress>111.11.11.13</IPAddress>
</DataNodeChild>
</ChildNodes>
</DataNodeBase>
<DataNodeBase xsi:type="Adaptor">
<Family>NetworkSettings</Family>
<Name>Network B</Name>
<IPAddress>111.22.11.1</IPAddress>
<ChildNodes>
<DataNodeChild xsi:type="SubResult">
<Family>NetworkSettings</Family>
<Name>Network BA</Name>
<IPAddress>111.11.11.12</IPAddress>
</DataNodeChild>
<DataNodeChild xsi:type="SubResult">
<Family>NetworkSettings</Family>
<Name>Network BB</Name>
<IPAddress>111.11.11.13</IPAddress>
</DataNodeChild>
</ChildNodes>
</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>
预期输出:由于没有添加表的规定,我已经为结果制作了hatml代码,请将此代码保存到html文件并查看预期输出。为了理解我已经制作了表格,我正在寻找xml中的输出但是如果有人制作xslt文件以表格格式给出/显示结果会很棒。
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<table>
<tr>
<td>Name</td><td>Status</td><td>OS01</td><td>OS02</td>
</tr>
<tr>
<td>Network AB</td><td>Equal</td><td>111.11.11.12</td><td>111.11.11.12</td>
</tr>
<tr>
<td>Network AB</td><td>Equal</td><td>111.11.11.13</td><td>111.11.11.13</td>
</tr>
<tr>
<td>Network BA</td><td>Unequal</td><td>111.11.11.21</td><td>111.11.11.12</td>
</tr>
<tr>
<td>Network BB</td><td>Unequal</td><td>111.11.11.31</td><td>111.11.11.13</td>
</tr>
</table>
</body>
</html>
答案 0 :(得分:0)
在回答之前,我假设您错过了XML中的命名空间声明,并且根元素应该看起来像这样(如果没有,您还需要从XSLT中删除所有命名空间的跟踪)
<OperatorStationCollection xmlns="http://www.w3.org">
在上一个问题中,您是按 DataNodeBase 进行分组,但在新问题中,您要按 DataNodeChild 进行分组。这意味着您真正需要做的就是在XSLT中用 DataNodeChild 替换所有出现的 DataNodeBase 。
唯一的另一个变化就是这一行
<xsl:value-of
select="key('networks', $network)[../../w3:Name=current()/w3:Name]/w3:IPAddress"/>
因为 DataNodeChild 嵌套了两个更高级别,所以必须相应地更改表达式
<xsl:value-of
select="key('networks', $network)[../../../../w3:Name=current()/w3:Name]/w3:IPAddress"/>
更好的是,要在任何级别应对它,可能就是这个
<xsl:value-of
select="key('networks', $network)[ancestor::w3:OperatorStation/w3:Name=current()/w3:Name]/w3:IPAddress"/>
就是这样。试试这个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:DataNodeChild" use="w3:Name"/>
<xsl:key name="networksAndIP" match="w3:DataNodeChild" 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:DataNodeChild[generate-id() = generate-id(key('networks', w3:Name)[1])]"/>
</table>
</xsl:template>
<xsl:template match="w3:DataNodeChild">
<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)[ancestor::w3:OperatorStation/w3:Name=current()/w3:Name]/w3:IPAddress"/>
</td>
</xsl:for-each>
</tr>
</xsl:template>
</xsl:stylesheet>