此问题与此帖Find maximum value of all child elements and get its parent element in XSLT有关。我错误地问了我的问题。实际上我需要的输出有点不同。我需要将站点节点ID与工作站点节点匹配,并找出为该站点工作更长时间的人员。
<root>
<Site id="S1">
<othernodes></othernodes>
</Site>
<Site id="S2">
<othernodes></othernodes>
</Site>
<Site id="S3">
<othernodes></othernodes>
</Site>
<WorkSite Person="P1" Site="S1">
<Hours>8</Hours>
</WorkSite>
<WorkSite Person="P1" Site="S2">
<Hours>2</Hours>
</WorkSite>
<WorkSite Person="P1" Site="S3">
<Hours>20</Hours>
</WorkSite>
<WorkSite Person="P2" Site="S1">
<Hours>6</Hours>
</WorkSite>
<WorkSite Person="P2" Site="S2">
<Hours>10</Hours>
</WorkSite>
<WorkSite Person="P2" Site="S3">
<Hours>21</Hours>
</WorkSite>
</root>
转换后的内容应该是这样的
<root>
<site id="S1">
<othernodes></othernodes>
<person>P1</person>
</site>
<site id="S2">
<othernodes></othernodes>
<person>P2</person>
</site>
<site id="S3">
<othernodes></othernodes>
<person>P1</person>
</site>
</root>
有人可以为此提供帮助吗?
答案 0 :(得分:1)
这样的东西?
<xsl:template match="/">
<root>
<xsl:apply-templates select="root/Site" />
</root>
</xsl:template>
<xsl:template match="/root/Site">
<xsl:variable name="sid" select="./@id" />
<site id="{./@id}">
<othernodes></othernodes>
<xsl:apply-templates select="/root/WorkSite[@Site = $sid]">
<xsl:sort select="./Hours" data-type="number" order="descending"/>
</xsl:apply-templates>
</site>
</xsl:template>
<xsl:template match="/root/WorkSite">
<xsl:if test="position() = 1">
<person><xsl:value-of select="./@Person" /></person>
</xsl:if>
</xsl:template>
答案 1 :(得分:1)
此XSLT 1.0转换:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kSiteByName" match="@Site" use="."/>
<xsl:key name="kWorksiteBySite"
match="WorkSite" use="@Site"/>
<xsl:key name="kSiteChildrenBySiteid"
match="Site/node()" use="../@id"/>
<xsl:variable name="vSites" select=
"/*/*/@Site[generate-id()
=
generate-id(key('kSiteByName',.)[1])
]"
/>
<xsl:template match="/">
<root>
<xsl:for-each select="$vSites">
<xsl:for-each select="key('kWorksiteBySite', .)">
<xsl:sort select="Hours" data-type="number"
order="descending"/>
<xsl:if test="position()=1">
<site id="{@Site}">
<xsl:copy-of select="key('kSiteChildrenBySiteid', @Site)"/>
<person><xsl:value-of select="@Person"/></person>
</site>
</xsl:if>
</xsl:for-each>
</xsl:for-each>
</root>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<root>
<Site id="S1">
<othernodes></othernodes>
</Site>
<Site id="S2">
<othernodes></othernodes>
</Site>
<Site id="S3">
<othernodes></othernodes>
</Site>
<WorkSite Person="P1" Site="S1">
<Hours>8</Hours>
</WorkSite>
<WorkSite Person="P1" Site="S2">
<Hours>2</Hours>
</WorkSite>
<WorkSite Person="P1" Site="S3">
<Hours>20</Hours>
</WorkSite>
<WorkSite Person="P2" Site="S1">
<Hours>6</Hours>
</WorkSite>
<WorkSite Person="P2" Site="S2">
<Hours>10</Hours>
</WorkSite>
<WorkSite Person="P2" Site="S3">
<Hours>21</Hours>
</WorkSite>
</root>
生成想要的正确结果:
<root>
<site id="S1">
<othernodes/>
<person>P1</person>
</site>
<site id="S2">
<othernodes/>
<person>P2</person>
</site>
<site id="S3">
<othernodes/>
<person>P2</person>
</site>
</root>
请注意:
使用Muenchian方法进行分组以查找所有不同的内容 网站价值。
通过按降序排序找到最大值的方式,并从排序的节点列表中获取第一个结果。 效率更高(O(N * log(N))比多次扫描节点序列(将每个值与值列表中的每个值进行比较),其具有O(N ^ N ^ 2)时间复杂度。
答案 2 :(得分:0)
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="BySite" match="WorkSite" use="@Site"/>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Site/*[last()]">
<xsl:call-template name="identity"/>
<person>
<xsl:value-of select="substring-after(
key('BySite',../@id)
[not(key('BySite',@Site)/Hours
> Hours)]
/@Person,
'P')" />
</person>
</xsl:template>
<xsl:template match="WorkSite"/>
</xsl:stylesheet>
输出:
<root>
<Site id="S1">
<othernodes></othernodes>
<person>1</person>
</Site>
<Site id="S2">
<othernodes></othernodes>
<person>2</person>
</Site>
<Site id="S3">
<othernodes></othernodes>
<person>2</person>
</Site>
</root>
答案 3 :(得分:0)
这就是我要做的。 (我添加了for-each
,以防您在一个网站上有多个完全相同的小时数。)
编辑:在我添加答案之前,我没有看到其他帖子中的XSLT 1.0要求。对此感到抱歉!
XML输入:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<Site id="S1">
<othernodes/>
</Site>
<Site id="S2">
<othernodes/>
</Site>
<Site id="S3">
<othernodes/>
</Site>
<WorkSite Person="P1" Site="S1">
<Hours>8</Hours>
</WorkSite>
<WorkSite Person="P1" Site="S2">
<Hours>2</Hours>
</WorkSite>
<WorkSite Person="P1" Site="S3">
<Hours>20</Hours>
</WorkSite>
<WorkSite Person="P2" Site="S1">
<Hours>6</Hours>
</WorkSite>
<WorkSite Person="P2" Site="S2">
<Hours>10</Hours>
</WorkSite>
<WorkSite Person="P2" Site="S3">
<Hours>21</Hours>
</WorkSite>
</root>
XSLT 2.0样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Site">
<xsl:variable name="vSiteId">
<xsl:value-of select="@id"/>
</xsl:variable>
<xsl:variable name="vMaxHours">
<xsl:value-of select="max(/root/WorkSite[@Site=$vSiteId]/Hours)"/>
</xsl:variable>
<site id="{@id}">
<xsl:apply-templates/>
<xsl:for-each select="/root/WorkSite[Hours=$vMaxHours]/@Person">
<person>
<xsl:value-of select="."/>
</person>
</xsl:for-each>
</site>
</xsl:template>
<xsl:template match="WorkSite"/>
</xsl:stylesheet>
XML输出:
<?xml version="1.0" encoding="UTF-8"?>
<root>
<site id="S1">
<othernodes/>
<person>P1</person>
</site>
<site id="S2">
<othernodes/>
<person>P2</person>
</site>
<site id="S3">
<othernodes/>
<person>P2</person>
</site>
</root>