我是XSLT的新手,并且正在寻求帮助,以根据其子级的组合值从xml文档中删除async function filterByAllowedDomain(context) {
var domains = await context.tables('domains')
.where({ allowed: true })
.read();
var categories = await context.tables('categories')
.where(function (ids) {
return this.domainId in ids;
}, domains.map(d => d.id))
.read();
context.query.where(function (ids) {
return this.categoryId in ids;
}, categories.map(c => c.id));
return context.execute(); }
的重复项。必须从具有相同值的每一组元素中输出tables
的最大值的元素。下面是我的示例xml文档和相应的所需输出。
<EMP>
所需的输出(基于合并的AIB_Position/AIB
,<Row_entry>
<Employees>
<Emp>
<Emp_id>E1</Emp_id>
<Emp_Name>Name1</Emp_Name>
<Country>C1</Country>
<AIB_Position>
<AIB>1500</AIB>
</AIB_Position>
</Emp>
<Emp>
<Emp_id>E2</Emp_id>
<Emp_Name>Name2</Emp_Name>
<Country>C2</Country>
<AIB_Position>
<AIB>1700</AIB>
</AIB_Position>
</Emp>
<Emp>
<Emp_id>E2</Emp_id>
<Emp_Name>Name2</Emp_Name>
<Country>C2</Country>
<AIB_Position>
<AIB>1800</AIB>
</AIB_Position>
</Emp>
</Employees>
</Row_entry>
,<Emp_id>
值删除了重复的Emp元素):
<Emp_Name>
答案 0 :(得分:1)
我认为您想要这样(直接使用XPath 2.0 max() function ):
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output indent="yes"/>
<xsl:template match="Employees">
<xsl:copy>
<xsl:for-each-group select="Emp" group-by="concat(Emp_id, '+', Emp_Name, '+', Country)">
<xsl:copy-of select="current-group()
[AIB_Position/AIB/number() = max(current-group()/AIB_Position/AIB/number())][1]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
并且如果您怀疑自己的XSLT处理器是白痴,例如多次计算max(),请使用更精确的定向转换:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output indent="yes"/>
<xsl:template match="Employees">
<xsl:copy>
<xsl:for-each-group select="Emp"
group-by="concat(Emp_id, '+', Emp_Name, '+', Country)">
<xsl:copy-of select=
"for $max in max(current-group()/AIB_Position/AIB/number())
return
current-group()[AIB_Position/AIB/number() = $max][1]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
在XSLT 2或更高版本中,使用for-each-group
,例如在XSLT 3中使用复合分组键,然后对每个组进行排序并输出最大值:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="Employees">
<xsl:copy>
<xsl:for-each-group select="Emp" composite="yes" group-by="Emp_id, Emp_Name, Country">
<xsl:for-each select="current-group()">
<xsl:sort select="AIB_Position/AIB" order="descending"/>
<xsl:if test="position() = 1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:for-each>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用支持更高阶sort
功能的XSLT 3处理器,您可以缩短要使用的代码
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:template match="Employees">
<xsl:copy>
<xsl:for-each-group select="Emp" composite="yes" group-by="Emp_id, Emp_Name, Country">
<xsl:sequence select="sort(current-group(), (), function($emp) { xs:integer($emp/AIB_Position/AIB) })[last()]"/>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://stackoverflow.com/tags/xslt-grouping/info详细介绍了如何在字符串X-LT 2中实现字符串组合,从而在XSLT 2中实现XSLT 3的组合分组密钥。