gpt4 book ai didi

xml - 停留在 XSLT 2.0 中的分组

转载 作者:数据小太阳 更新时间:2023-10-29 02:41:12 27 4
gpt4 key购买 nike

我有一个这样的输入文件

<items>
<item>
<id>5</id>
<name>Harry</name>
<age>18</age>
<color>blue</color>
</item>
<item>
<id>5</id>
<name>Harry</name>
<age>18</age>
<fav_food>pizza</fav_food>
</item>
<item>
<id>5</id>
<name>Harry</name>
<age>18</age>
<is_single>true</is_single>
</item>
</items>

我想对元素进行分组,使文件看起来像这样

<items>
<item>
<id>5</id>
<name>Harry</name>
<age>18</age>
<color>blue</color>
<fav_food>pizza</fav_food>
<is_single>true</is_single>
</item>
</items>

编辑 - 按照此链接 (XSLT Consolidating data when ID is the same) 进行 XSLT 转换,但这不会打印任何内容。

这是我的转换(使用 XSLT 2.0)-

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="items">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>

<xsl:template match="item">
<xsl:apply-templates select="@*" />
<xsl:for-each-group select="item" group-by="id">
<item>
<id><xsl:value-of select="current-grouping-key()"/></id>
<xsl:apply-templates select="current-group()" />
</item>
</xsl:for-each-group>
</xsl:template>

<xsl:template match="@*|node()[not(self::*)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

最佳答案

您遇到的主要问题是您有一个匹配 item 元素的模板:

<xsl:template match="item">

但是在其中,您有一个 xsl:for-each-group 也查找 item 元素

<xsl:for-each-group select="item" group-by="id">

这意味着您正在寻找 item 元素,它们是其他 item 元素的子元素,而 XML 中没有这些元素。我认为您需要在此处将前两个模板合并为一个:

<xsl:template match="items">
<xsl:for-each-group select="item" group-by="id">
<item>
....

不清楚的是 item 元素中的哪些元素将被重复。它会永远是身份证、姓名和年龄吗?不过,这里最好保持灵活,并假设只有 id 是公共(public)元素。我还将假设如果两个元素重复(如 name),它将始终具有相同的值。

因此,要获得所有其他不同的非 id 元素,您可以对元素名称进行更多分组

<xsl:for-each-group select="current-group()/*[not(self::id)]" group-by="local-name()">

然后,在此循环中,您可以只输出元素。

试试这个 XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />

<xsl:template match="items">
<xsl:for-each-group select="item" group-by="id">
<item>
<id><xsl:value-of select="current-grouping-key()"/></id>
<xsl:for-each-group select="current-group()/*[not(self::id)]" group-by="local-name()">
<xsl:apply-templates select="self::*" />
</xsl:for-each-group>
</item>
</xsl:for-each-group>
</xsl:template>

<xsl:template match="@*|node()[not(self::*)]">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>

<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>

</xsl:stylesheet>

当应用于您的 XML 时,输出如下

<item>
<id>5</id>
<name>Harry</name>
<age>18</age>
<color>blue</color>
<fav_food>pizza</fav_food>
<is_single>true</is_single>
</item>

关于xml - 停留在 XSLT 2.0 中的分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17282708/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com