编写XML转CSV的XSLT:排序孙节点并取最大月份对应Sales_Program-ID
搞定!XSLT实现按孙节点排序并提取最大月份对应的Sales_Program-ID
没问题,我来帮你实现这个需求!核心逻辑就是:对所有Month孙节点排序,找到月份值最大的那个,然后提取它对应的Sales_Program-ID,输出成CSV格式。下面分情况给你示例代码,你可以根据自己的XML结构调整。
首先假设你的输入XML结构是这样的(如果有差异,调整节点路径即可):
<Root> <Sales_Group> <Sales_Program-ID>SP-001</Sales_Program-ID> <Details> <Month>2024-03</Month> <!-- 其他子节点 --> </Details> </Sales_Group> <Sales_Group> <Sales_Program-ID>SP-002</Sales_Program-ID> <Details> <Month>2024-05</Month> <!-- 其他子节点 --> </Details> </Sales_Group> <Sales_Group> <Sales_Program-ID>SP-003</Sales_Program-ID> <Details> <Month>2024-01</Month> <!-- 其他子节点 --> </Details> </Sales_Group> </Root>
情况1:每个Sales_Group对应一个Month节点
直接用下面的XSLT就能搞定:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 用key把Sales_Group和对应的Month关联起来,方便快速查找 --> <xsl:key name="group-by-month" match="Sales_Group" use="Details/Month"/> <!-- 处理根节点的主模板 --> <xsl:template match="/"> <!-- 先输出CSV表头 --> <xsl:text>Sales_Program-ID,Max_Month </xsl:text> <!-- 取所有不重复的Month节点,按降序排序 --> <xsl:for-each select="//Month[not(. = preceding::Month)]"> <xsl:sort select="." order="descending"/> <!-- 只取排序后的第一个(也就是最大的月份),输出对应的ID和月份 --> <xsl:if test="position() = 1"> <xsl:value-of select="key('group-by-month', .)/Sales_Program-ID"/> <xsl:text>,</xsl:text> <xsl:value-of select="."/> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>
情况2:每个Sales_Group对应多个Month节点
如果你的XML里一个销售组有多个月份数据,那得先算出每个组的最大月份,再整体排序取最大的那个对应的ID:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <xsl:template match="/"> <xsl:text>Sales_Program-ID,Max_Month </xsl:text> <!-- 先遍历每个Sales_Group,算出每个组的最大月份,存成临时节点 --> <xsl:for-each select="Root/Sales_Group"> <xsl:variable name="current-group-max-month"> <xsl:for-each select="Details/Month"> <xsl:sort select="." order="descending"/> <xsl:if test="position() = 1"> <xsl:value-of select="."/> </xsl:if> </xsl:for-each> </xsl:variable> <!-- 生成临时节点存组的ID和最大月份 --> <xsl:variable name="group-temp"> <group> <program-id><xsl:value-of select="Sales_Program-ID"/></program-id> <max-month><xsl:value-of select="$current-group-max-month"/></max-month> </group> </xsl:variable> <xsl:copy-of select="$group-temp"/> </xsl:for-each> <!-- 对所有组的最大月份降序排序,取第一个输出 --> <xsl:for-each select="document('')//group"> <xsl:sort select="max-month" order="descending"/> <xsl:if test="position() = 1"> <xsl:value-of select="program-id"/> <xsl:text>,</xsl:text> <xsl:value-of select="max-month"/> </xsl:if> </xsl:for-each> </xsl:template> </xsl:stylesheet>
预期输出
针对情况1的XML,输出会是:
Sales_Program-ID,Max_Month SP-002,2024-05
针对情况2的XML(假设SP-001有2024-03和2024-06两个月份),输出会是:
Sales_Program-ID,Max_Month SP-001,2024-06
如果你的XML结构还有特殊情况,比如节点层级不同,只要调整XSLT里的节点路径(比如把Details/Month改成你的实际路径)就行,核心逻辑不变。
内容的提问来源于stack exchange,提问作者Soma Kuhu
相关产品推荐
相关产品推荐

