下面是我的输入 XML。我想根据用户名对下面的 XML 进行分组,并删除 HierarchyLocation 中的任何重复项
下面是我输入的 XML
<data>
<UploadUser>
<User>
<EmailAddress>test1.com</EmailAddress>
<Username>User1</Username>
<Replace>True</Replace>
</User>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup1</UserGroup>
<Location>43737</Location>
</HierarchyLocations>
</UploadUser>
<UploadUser>
<User>
<EmailAddress>test2.com</EmailAddress>
<Username>User2</Username>
<Replace>True</Replace>
</User>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup2</UserGroup>
<Location>43737</Location>
</HierarchyLocations>
</UploadUser>
<UploadUser>
<User>
<EmailAddress>test2.com</EmailAddress>
<Username>User2</Username>
<Replace>True</Replace>
</User>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup2</UserGroup>
<Location>43737</Location>
</HierarchyLocations>
</UploadUser>
<UploadUser>
<User>
<EmailAddress>test2.com</EmailAddress>
<Username>User2</Username>
<Replace>True</Replace>
</User>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup3</UserGroup>
<Location>5230</Location>
</HierarchyLocations>
</UploadUser>
</data>
以下是我的预期输出
<data>
<UploadUser>
<User>
<EmailAddress>test1.com</EmailAddress>
<Username>User1</Username>
<Hierarchies>
<Replace>True</Replace>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup1</UserGroup>
<Location>43737</Location>
</HierarchyLocations>
</Hierarchies>
</User>
<User>
<EmailAddress>test2.com</EmailAddress>
<Username>User2</Username>
<Hierarchies>
<Replace>True</Replace>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup2</UserGroup>
<Location>43737</Location>
</HierarchyLocations>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup3</UserGroup>
<Location>5230</Location>
</HierarchyLocations>
</Hierarchies>
</User>
</UploadUser>
</data>
我尝试了下面的 XSLT,但无法删除重复的 HierarchyLocations。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="data">
<xsl:copy>
<UploadUser>
<xsl:for-each-group select="UploadUser" group-by="User/Username">
<User>
<xsl:apply-templates select="current-group()[1]/User/EmailAddress" />
<xsl:apply-templates select="current-group()[1]/User/Username" />
<Hierarchies>
<xsl:apply-templates select="current-group()[1]/User/Replace" />
<xsl:for-each select="current-group()">
<xsl:apply-templates select="HierarchyLocations[not(Location=preceding-sibling::HierarchyLocations/Location)]" />
</xsl:for-each>
</Hierarchies>
</User>
</xsl:for-each-group>
</UploadUser>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
使用上述 XSLT 输出。 层次结构位置与用户名“user2”重复,我需要删除比较所有 3 个字段(层次结构、用户组和位置)。我尝试不使用“preceding-sibling”来复制它,但仍然被复制了。
<data>
<UploadUser>
<User>
<EmailAddress>test1.com</EmailAddress>
<Username>User1</Username>
<Hierarchies>
<Replace>True</Replace>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup1</UserGroup>
<Location>43737</Location>
</HierarchyLocations>
</Hierarchies>
</User>
<User>
<EmailAddress>test2.com</EmailAddress>
<Username>User2</Username>
<Hierarchies>
<Replace>True</Replace>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup2</UserGroup>
<Location>43737</Location>
</HierarchyLocations>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup2</UserGroup>
<Location>43737</Location>
</HierarchyLocations>
<HierarchyLocations>
<Hierarchy>Hierarchy</Hierarchy>
<UserGroup>UserGroup3</UserGroup>
<Location>5230</Location>
</HierarchyLocations>
</Hierarchies>
</User>
</UploadUser>
</data>
只需在当前组上再进行一次分组即可:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="data">
<xsl:copy>
<UploadUser>
<xsl:for-each-group select="UploadUser" group-by="User/Username">
<User>
<xsl:copy-of select="User/(EmailAddress|Username)"/>
<Hierarchies>
<xsl:copy-of select="User/Replace"/>
<xsl:for-each-group select="current-group()/HierarchyLocations" group-by="string-join((Hierarchy, UserGroup, Location), '|')">
<xsl:copy-of select="."/>
</xsl:for-each-group>
</Hierarchies>
</User>
</xsl:for-each-group>
</UploadUser>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意,在
xsl:for-each-group
中,组的第一项是上下文项 - 因此您可以摆脱那些尴尬的 current-group()[1]/something
表达式。
这是 xslt,其中前一个同级部分的部分被重写。您位于当前组内,因此您可以迭代并使用索引来引用先前的迭代。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="data">
<xsl:copy>
<UploadUser>
<xsl:for-each-group select="UploadUser" group-by="User/Username">
<User>
<xsl:apply-templates select="current-group()[1]/User/EmailAddress" />
<xsl:apply-templates select="current-group()[1]/User/Username" />
<Hierarchies>
<xsl:apply-templates select="current-group()[1]/User/Replace" />
<xsl:variable name="sequence" select="current-group()"/>
<xsl:for-each select="1 to count($sequence)">
<xsl:variable name="position" select="."/>
<xsl:apply-templates select="$sequence[$position]/HierarchyLocations[not(Location=$sequence[$position -1]/HierarchyLocations/Location)]" />
</xsl:for-each>
</Hierarchies>
</User>
</xsl:for-each-group>
</UploadUser>
</xsl:copy>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>