使用 XSLT 将具有相同 ID 的元素 (XML) 合并到 txt 文件
Merge Elements (XML) With Same ID to txt file using XSLT
我有一个任务需要遍历 XML 文档并合并具有相同 ID 的 elements/nodes。输出应该是一个 csv 文件(用于进一步处理),其中每一行都有固定的长度。根据节点的值,该值需要放在输出中的特定位置。
这是 XML 的 示例:
<root>
<User>
<UserID>55555</UserID>
<Value>Active</Value>
</User>
<User>
<UserID>55555</UserID>
<Value>Admin</Value>
</User>
<User>
<UserID>55555</UserID>
<Value>Eligible</Value>
</User>
<User>
<UserID>123456</UserID>
<Value>Active</Value>
</User>
</root>
我的期望输出将是:
User ID, Active, Admin, Eligible
55555, Y, Y, Y,
123456, Y, N, N,
请注意,值始终相同(活跃、管理员和合格),但用户可以像示例中那样拥有不同数量的值。
目前我得到的是:
<xsl:template match="/root">
<Header>
<xsl:text>User ID</xsl:text>
<xsl:value-of select="$comma"/>
<xsl:text>Active</xsl:text>
<xsl:value-of select="$comma"/>
<xsl:text>Admin</xsl:text>
<xsl:value-of select="$comma"/>
<xsl:text>Eligible</xsl:text>
<xsl:text>
</xsl:text>
</Header>
<xsl:for-each-group select="User" group-by="UserID">
<!-- User ID -->
<xsl:value-of select="UserID"/>
<xsl:value-of select="$comma"/>
<xsl:for-each-group select="current-group()" group-by="Value">
<xsl:value-of select="current-grouping-key()"/>
<xsl:value-of select="$comma"/>
</xsl:for-each-group>
<xsl:value-of select="$lineFeed"/>
</xsl:for-each-group>
</xsl:template>
这个组并选择了正确的元素,但是我需要将它们放在正确的 headers 下(比如具有所需输出的 axample)。
谁能给我指出正确的方向?任何帮助将不胜感激。
如果我理解正确(非常大的如果!),你想做这样的事情:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/root">
<!-- header -->
<xsl:text>User ID, Active, Admin, Eligible </xsl:text>
<!-- rows -->
<xsl:for-each-group select="User" group-by="UserID">
<!-- User ID -->
<xsl:value-of select="UserID"/>
<xsl:text>, </xsl:text>
<!-- Active -->
<xsl:value-of select="if (current-group()/Value[.='Active']) then 'Y' else'N'"/>
<xsl:text>, </xsl:text>
<!-- Admin -->
<xsl:value-of select="if (current-group()/Value[.='Admin']) then 'Y' else'N'"/>
<xsl:text>, </xsl:text>
<!-- Eligible -->
<xsl:value-of select="if (current-group()/Value[.='Eligible']) then 'Y' else'N'"/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
或更简洁:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/root">
<!-- header -->
<xsl:text>User ID, Active, Admin, Eligible </xsl:text>
<!-- rows -->
<xsl:for-each-group select="User" group-by="UserID">
<xsl:value-of select="UserID, for $t in ('Active', 'Admin', 'Eligible') return if (current-group()/Value[.=$t]) then 'Y' else 'N'" separator=", "/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
请注意,结果与您发布的略有不同:每条记录中没有尾随逗号。
我有一个任务需要遍历 XML 文档并合并具有相同 ID 的 elements/nodes。输出应该是一个 csv 文件(用于进一步处理),其中每一行都有固定的长度。根据节点的值,该值需要放在输出中的特定位置。
这是 XML 的 示例:
<root>
<User>
<UserID>55555</UserID>
<Value>Active</Value>
</User>
<User>
<UserID>55555</UserID>
<Value>Admin</Value>
</User>
<User>
<UserID>55555</UserID>
<Value>Eligible</Value>
</User>
<User>
<UserID>123456</UserID>
<Value>Active</Value>
</User>
</root>
我的期望输出将是:
User ID, Active, Admin, Eligible
55555, Y, Y, Y,
123456, Y, N, N,
请注意,值始终相同(活跃、管理员和合格),但用户可以像示例中那样拥有不同数量的值。
目前我得到的是:
<xsl:template match="/root">
<Header>
<xsl:text>User ID</xsl:text>
<xsl:value-of select="$comma"/>
<xsl:text>Active</xsl:text>
<xsl:value-of select="$comma"/>
<xsl:text>Admin</xsl:text>
<xsl:value-of select="$comma"/>
<xsl:text>Eligible</xsl:text>
<xsl:text>
</xsl:text>
</Header>
<xsl:for-each-group select="User" group-by="UserID">
<!-- User ID -->
<xsl:value-of select="UserID"/>
<xsl:value-of select="$comma"/>
<xsl:for-each-group select="current-group()" group-by="Value">
<xsl:value-of select="current-grouping-key()"/>
<xsl:value-of select="$comma"/>
</xsl:for-each-group>
<xsl:value-of select="$lineFeed"/>
</xsl:for-each-group>
</xsl:template>
这个组并选择了正确的元素,但是我需要将它们放在正确的 headers 下(比如具有所需输出的 axample)。
谁能给我指出正确的方向?任何帮助将不胜感激。
如果我理解正确(非常大的如果!),你想做这样的事情:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/root">
<!-- header -->
<xsl:text>User ID, Active, Admin, Eligible </xsl:text>
<!-- rows -->
<xsl:for-each-group select="User" group-by="UserID">
<!-- User ID -->
<xsl:value-of select="UserID"/>
<xsl:text>, </xsl:text>
<!-- Active -->
<xsl:value-of select="if (current-group()/Value[.='Active']) then 'Y' else'N'"/>
<xsl:text>, </xsl:text>
<!-- Admin -->
<xsl:value-of select="if (current-group()/Value[.='Admin']) then 'Y' else'N'"/>
<xsl:text>, </xsl:text>
<!-- Eligible -->
<xsl:value-of select="if (current-group()/Value[.='Eligible']) then 'Y' else'N'"/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
或更简洁:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/root">
<!-- header -->
<xsl:text>User ID, Active, Admin, Eligible </xsl:text>
<!-- rows -->
<xsl:for-each-group select="User" group-by="UserID">
<xsl:value-of select="UserID, for $t in ('Active', 'Admin', 'Eligible') return if (current-group()/Value[.=$t]) then 'Y' else 'N'" separator=", "/>
<xsl:text> </xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
请注意,结果与您发布的略有不同:每条记录中没有尾随逗号。