第一个for-each-group
几乎可以工作。它找到了我需要它找到的所有内容,除了一些 sachbegriff 节点(即它找到了 47 个,但缺少一个等)。当我进行第二次传递(另一个针对每个组)时,明确要求这些节点,我得到了它们。 (当然,现在我有一些节点两次并且顺序困惑)。有什么想法为什么我第一次没有得到它们吗?
现在已尝试使用 Saxon-HE .NET 9.x 和 10.2。
<xsl:for-each-group select="/museumPlusExport/sammlungsobjekt[@objId eq $id]/*" group-by="string()">
<xsl:sort select="name()" />
<xsl:apply-templates select="."/>
</xsl:for-each-group>
<xsl:for-each-group select="/museumPlusExport/sammlungsobjekt[@objId eq $id]/sachbegriff" group-by="string()">
<xsl:apply-templates select="."/>
</xsl:for-each-group>
基于以下 Martin Honnen 的回答/解释的解决方案/已解决 XSLT 2.0
<xsl:for-each-group select="/museumPlusExport/sammlungsobjekt[@objId eq $id]/*"
group-by="concat(name(), '|', string())">
<xsl:sort select="name()" />
<xsl:variable name="name" select="name()"/>
<xsl:apply-templates select="."/>
</xsl:for-each-group>
XSLT 3.0
<xsl:for-each-group select="/museumPlusExport/sammlungsobjekt[@objId eq $id]/*"
composite="yes" group-by="node-name(), string()">
<xsl:sort select="name()" />
<xsl:variable name="name" select="name()"/>
<xsl:apply-templates select="."/>
</xsl:for-each-group>
最佳答案
代码
<xsl:for-each-group select="/museumPlusExport/sammlungsobjekt[@objId eq $id]/*" group-by="string()">
<xsl:sort select="name()" />
<xsl:apply-templates select="."/>
</xsl:for-each-group>
对 /museumPlusExport/sammlungsobjekt[@objId eq $id]
的所有子元素进行分组通过它们的字符串值,然后使用 <xsl:apply-templates select="."/>
推送每组中的第一个元素到匹配的模板。如果有的话sachbegriff
元素不会以这种方式出现,因为它们与具有相同字符串值但位于它们之前的其他元素组合在一起。
我无法判断您想要哪个结果,是否想真正按字符串值对所有子元素进行分组,但只进一步处理每个组中的第一项。如果您想将每组中的所有项目推送到模板,您可以使用 <xsl:apply-templates select="current-group()"/>
。但通常情况下,通过分组,人们想要包装和/或积累一些元素,所以在我看来你也不太可能想要这样做。
我认为最好展示输入和所需输出的小型、有代表性的样本,以及将输入映射到输出的标准。
根据您对问题的编辑,如果您确实使用 XSLT 3,而不是 group-by="concat(name(), '|', string())"
我想你可以使用composite="yes" group-by="node-name(), string()"
用于分组。
关于xml - 为什么xsl是:for-each-group missing some elements?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64335452/