我想知道如何通过内容对XML元素进行合并/分组/组合,以使分组的值仅出现一次,并将其余节点合并到结果中,就像在现代SQL语句中将结果分组一样MariaDB(结果中没有重复项)。
我已经在寻找解决方案,但是此处或其他地方给出的示例与我的要求不符-调整后也没有。
我猜想<lemma>
的位置可能是个问题。另一方面,我认为/希望以某种方式仍然可以找到解决方案。
我的文档的简化结构和所需的输出:
XML:
<root>
<artikel>
<lemma-position>
<lemma>Abend</lemma>
<info>aaa</info>
</lemma-position>
<bedeutungsposition nr="1a">
<bedeutung>Zeit am Ende des Tages</bedeutung>
</bedeutungsposition>
<bedeutungsposition nr="1b">
<bedeutung>
was anderes
</bedeutung>
</bedeutungsposition>
</artikel>
<artikel>
<lemma-position>
<lemma>Abend</lemma>
<info>bbb</info>
</lemma-position>
<bedeutungsposition nr="1">
<bedeutung>abcdefg</bedeutung>
</bedeutungsposition>
<bedeutungsposition nr="2">
<bedeutung>japoisdfoiasjdfoasjdfl</bedeutung>
</bedeutungsposition>
</artikel>
</root>
在此示例中,节点<lemma>
包含“ Abend”,这应该是分组的值。
所需的输出:
<root>
<artikel>
<lemma-position>
<lemma>Abend</lemma>
<info>aaa</info>
<info>bbb</lemma>
</lemma-position>
<bedeutungsposition nr="1">
<bedeutung>abcdefg</bedeutung>
</bedeutungsposition>
<bedeutungsposition nr="1a">
<bedeutung>Zeit am Ende des Tages</bedeutung>
</bedeutungsposition>
<bedeutungsposition nr="1b">
<bedeutung>
was anderes
</bedeutung>
</bedeutungsposition>
<bedeutungsposition nr="2">
<bedeutung>japoisdfoiasjdfoasjdfl</bedeutung>
</bedeutungsposition>
</artikel>
</root>
我得到的是一个未合并的副本,即XML输入或它的一部分,但根本没有合并。到目前为止,我已经尝试了几种方法,其中的基础总是像这样:
<xsl:template match="/">
<xsl:copy>
<xsl:for-each-group select="artikel" group-by="//lemma">
<xsl:copy-of select="current-group()//lemma/*" />
<!--
I also placed some other paths and expressions here or above to
select the elements differently, without success however.
-->
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
我也尝试过使用distinct-values
等进行xQuery,但是它也不起作用(没有重复项)。
我正在用Oxygen和baseX进行测试,它们都连接到Saxon-9.8 HE,所以实际上应该没问题。 XSLT中的一种解决方案与xQuery中的一种解决方案一样值得赞赏
答案 0 :(得分:3)
我认为主要模板是
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="artikel" group-by="lemma-position/lemma">
<xsl:copy>
<lemma-position>
<lemma>
<xsl:value-of select="current-grouping-key()"/>
</lemma>
<xsl:apply-templates select="current-group()/lemma-position/(* except lemma)"/>
</lemma-position>
<xsl:apply-templates select="current-group()/(* except lemma-position)">
<xsl:sort select="@nr"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
与身份转换(例如,在xsl:mode on-no-match="shallow-copy"
声明的XSLT 3中)一起获得https://xsltfiddle.liberty-development.net/gWvjQfR:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="#all"
version="3.0">
<xsl:mode on-no-match="shallow-copy"/>
<xsl:output method="xml" indent="yes"/>
<xsl:template match="root">
<xsl:copy>
<xsl:for-each-group select="artikel" group-by="lemma-position/lemma">
<xsl:copy>
<lemma-position>
<lemma>
<xsl:value-of select="current-grouping-key()"/>
</lemma>
<xsl:apply-templates select="current-group()/lemma-position/(* except lemma)"/>
</lemma-position>
<xsl:apply-templates select="current-group()/(* except lemma-position)">
<xsl:sort select="@nr"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
您可以在BaseX XQuery中使用
<root>
{
for $artikel in root/artikel
group by $lemma := $artikel/lemma-position/lemma
return
<artikel>
<lemma-position>
<lemma>{$lemma}</lemma>
{
$artikel/lemma-position/(* except lemma)
}
</lemma-position>
{
sort($artikel/(* except lemma-position), (), function($el) { $el/@nr })
}
</artikel>
}
</root>