如何使用XSLT将具有相同名称和相同属性的所有同级元素合并到单个元素中?转换也应递归地应用于正在合并的元素的子元素.这是源文件:
<?xml version="1.0"?> <Root> <Element id="UniqueId1"> <SubElement1/> <SubElement2> <LeafElement1/> </SubElement2> </Element> <Element id="UniqueId1"> <SubElement2> <LeafElement1/> <LeafElement2/> </SubElement2> <SubElement3/> </Element> <Element id="UniqueId2"> <SubElement1/> <SubElement4/> </Element> </Root>@H_301_2@它应该转变为:
<?xml version="1.0"?> <Root> <Element id="UniqueId1"> <SubElement1/> <SubElement2> <LeafElement1/> <LeafElement2/> </SubElement2> <SubElement3/> </Element> <Element id="UniqueId2"> <SubElement1/> <SubElement4/> </Element> </Root>@H_301_2@具有相同名称和属性的任何元素都合并为一个元素.然后,他们的孩子接受检查.如果其中任何一个具有相同的名称和相同的属性,则将它们组合在一起.此转换以递归方式应用于所有元素.
编辑:为了澄清,所有这些条件必须为两个要合并的元素.
>它们具有相同的元素名称
>它们具有相同的属性
>每个相应属性的值都相同
>他们是兄弟姐妹(递归应用,因此在考虑孩子之前,任何相同的父元素都会被合并和组合)这些元素是相同的,应该合并:
>< Item />和< Item /> (同名,相同属性)
>< Item Attr =“foo”/>和< Item Attr =“foo”/> (同名,相同属性)这些元素不相同,不应合并:
>< Item />和< SubItem /> (不同的名字)
>< Item Attr =“foo”/>和< Item /> (不同的属性)
>< Item Attr =“foo”/>和< Item Attr =“bar”/> (不同的属性值)
这应该做的工作:
原文链接:https://www.f2er.com/xml/293043.html<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" indent="yes"/> <xsl:key name="atts-by-name" match="@*" use="name()"/> <xsl:template match="Root"> <xsl:copy> <xsl:call-template name="merge"> <xsl:with-param name="elements" select="*"/> </xsl:call-template> </xsl:copy> </xsl:template> <xsl:template name="merge"> <xsl:param name="elements"/> <xsl:for-each select="$elements"> <xsl:variable name="same-elements" select="$elements[name()=name(current()) and count(@*)=count(current()/@*) and count(@*[. = key('atts-by-name',name())[generate-id(..)=generate-id(current())]])=count(@*)]"/> <xsl:if test="generate-id($same-elements[1]) = generate-id()"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:call-template name="merge"> <xsl:with-param name="elements" select="$same-elements/*"/> </xsl:call-template> </xsl:copy> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>@H_301_2@