如何优化XSLT遍历xsi:type=TPFC节点及复用重复select语句
XSLT遍历TPFC节点优化方案
优化思路
- 一次性匹配所有
xsi:type="TPFC"的节点:不管是顶层<TPFC>节点还是嵌套的<Parent>节点,只要属性符合要求就统一选中,不需要分开写两次循环 - 抽离重复的行输出逻辑:将CSV行的生成逻辑封装为可复用的模板,避免重复代码
- 修正全局路径问题:原代码中
//Parent是全局查找,多Package场景下会出现数据错乱,改为相对路径匹配更安全
优化后完整代码
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <xsl:output method="text" encoding="utf-8"/> <!-- 分隔符配置 --> <xsl:variable name="separator" select="'|'"/> <!-- 换行符配置 --> <xsl:variable name="newline" select="' '"/> <!-- 复用模板:输出单条TPFC记录 --> <xsl:template name="outputTPFCRow"> <xsl:param name="node" select="."/> <xsl:param name="productId"/> <!-- 计算当前节点层级:从根TPFC开始数,根节点层级为1 --> <xsl:variable name="level" select="count($node/ancestor-or-self::*[@xsi:type='TPFC'])"/> <!-- 计算总层级:整棵TPFC树的最大深度 --> <xsl:variable name="totalLevel" select="count(max($node/ancestor::Package//*[@xsi:type='TPFC']/count(ancestor-or-self::*[@xsi:type='TPFC'])))"/> <!-- id列:当前节点+所有后代TPFC的Name拼接 --> <xsl:value-of select="$node/descendant-or-self::*[@xsi:type='TPFC']/translate(Name,' ','')" separator="_"/> <xsl:value-of select="$separator"/> <!-- name列 --> <xsl:value-of select="$node/Name"/> <xsl:value-of select="$separator"/> <!-- description列 --> <xsl:value-of select="$node/Description"/> <xsl:value-of select="$separator"/> <!-- parent_name列 --> <xsl:value-of select="$node/parent::*/Name"/> <xsl:value-of select="$separator"/> <!-- parent_id列 --> <xsl:value-of select="$node/parent::*/@ID"/> <xsl:value-of select="$separator"/> <!-- level列 --> <xsl:value-of select="$level"/> <xsl:value-of select="$separator"/> <!-- total_level列 --> <xsl:value-of select="$totalLevel"/> <xsl:value-of select="$separator"/> <!-- product_offering_id列 --> <xsl:value-of select="$productId"/> <xsl:value-of select="$newline"/> </xsl:template> <xsl:template match="/Root"> <!-- 表头 --> <xsl:text>id|name|description|parent_name|parent_id|level|total_level|product_offering_id</xsl:text> <xsl:value-of select="$newline"/> <!-- 数据遍历 --> <xsl:for-each select="Package"> <xsl:variable name="productId" select="Business_ID" /> <!-- 一次性选中当前Package下所有xsi:type=TPFC的节点 --> <xsl:for-each select=".//*[@xsi:type='TPFC']"> <xsl:call-template name="outputTPFCRow"> <xsl:with-param name="productId" select="$productId"/> </xsl:call-template> </xsl:for-each> <xsl:value-of select="$newline"/> </xsl:for-each> </xsl:template> </xsl:stylesheet>
输出说明
针对你提供的示例XML,运行上述代码后输出的CSV内容如下:
id|name|description|parent_name|parent_id|level|total_level|product_offering_id AM_Mob1_Mob2|AM|||76|1|3|001233 Mob1_Mob2|Mob1|Mob1|AM|11d|2|3|001233 Mob2|Mob2|Mob2|Mob1|12F|3|3|001233
内容的提问来源于stack exchange,提问作者Sri-nidhi
相关产品推荐
相关产品推荐

