XSLT中删除Value后无法移除空ValueGroup的问题求助
问题:移除空的ValueGroup标签失败
需求:当tec_att_ignore_basic_data_text属性对应的Value的ID为Y时,删除prd_att_description的ValueGroup下对应QualifierID的Value;若删除后该ValueGroup为空,则移除整个ValueGroup标签。目前Value删除功能正常,但空的ValueGroup无法被移除。
输入XML
<?xml version="1.0" encoding="UTF-8"?> <STEP-ProductInformation> <Products> <Product> <Values> <ValueGroup AttributeID="tec_att_ignore_basic_data_text"> <Value ID="Y" QualifierID="en-US">Yes</Value> <Value ID="Y" QualifierID="de-DE">Yes</Value> </ValueGroup> <ValueGroup AttributeID="prd_att_description"> <Value QualifierID="en-US"> english text </Value> <Value QualifierID="de-DE"> german text </Value> </ValueGroup> </Values> </Product> </Products> </STEP-ProductInformation>
当前XSL代码(无法移除空ValueGroup)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="lov" match="ValueGroup[@AttributeID='tec_att_ignore_basic_data_text']/Value" use="@QualifierID" /> <!-- identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="ValueGroup[@AttributeID='prd_att_description']/Value[key('lov', @QualifierID)/@ID='Y']"/> <xsl:template match="ValueGroup[@AttributeID='prd_att_description' and not(Value)]"/> </xsl:stylesheet>
问题原因
XSLT的模板匹配基于原始输入文档的节点状态,而非前一个模板处理后的结果。原文档中prd_att_description的ValueGroup存在Value子节点,所以第二个匹配空ValueGroup的模板永远不会触发。
解决方案
直接在匹配prd_att_description的ValueGroup时,先筛选出不需要删除的Value,仅当存在剩余Value时才保留该ValueGroup:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:key name="lov" match="ValueGroup[@AttributeID='tec_att_ignore_basic_data_text']/Value" use="@QualifierID" /> <!-- 身份模板:默认复制所有节点 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 专门处理prd_att_description的ValueGroup --> <xsl:template match="ValueGroup[@AttributeID='prd_att_description']"> <!-- 筛选出不需要删除的Value:即对应QualifierID的lov节点ID不为Y --> <xsl:variable name="remaining-values" select="Value[not(key('lov', @QualifierID)/@ID='Y')]"/> <!-- 仅当有剩余Value时,才复制该ValueGroup并输出剩余节点 --> <xsl:if test="$remaining-values"> <xsl:copy> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="$remaining-values"/> </xsl:copy> </xsl:if> </xsl:template> </xsl:stylesheet>
该方案将Value过滤和ValueGroup留存判断合并到同一个模板中,直接基于原始节点计算剩余Value的数量,避免了依赖处理后的节点状态,从而解决空ValueGroup无法移除的问题。
内容的提问来源于stack exchange,提问作者Saffe
相关产品推荐
相关产品推荐

