如何实现递归删除所有紧跟<MULTIPLE>的<AGGREGATION>节点?
嘿,我明白你的问题了——你需要删除每一个紧跟在<MULTIPLE>节点之后的<AGGREGATION>节点,但当前的XSLT只能处理第一个,对吧?别担心,我们可以通过调整XSLT的模板逻辑来实现全局匹配删除,而不是只处理一次。
核心思路
现有代码只删第一个的原因,大概率是匹配规则只命中了第一个符合条件的节点,或者没有递归遍历整个XML树的所有层级。我们需要让XSLT自动遍历所有节点,对每一个满足“紧跟在<MULTIPLE>之后”的<AGGREGATION>执行删除操作。
完整解决方案代码
下面是可以实现需求的XSLT代码,我会逐一解释关键部分:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- 身份模板:默认复制所有节点和属性,除非被其他模板覆盖 --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 匹配所有紧跟在<MULTIPLE>之后的<AGGREGATION>节点,直接跳过输出(即删除) --> <xsl:template match="AGGREGATION[preceding-sibling::*[1][self::MULTIPLE]]"/> </xsl:stylesheet>
关键规则说明
- 身份模板:这是XSLT的基础模板,作用是默认复制XML中所有的节点、属性和文本内容。只有当某个节点被其他模板匹配时,才会执行对应的逻辑,这样能保证除了要删除的节点外,其他内容都原样保留。
- 删除匹配规则:
match="AGGREGATION[preceding-sibling::*[1][self::MULTIPLE]]"这条规则的意思是:- 匹配所有
<AGGREGATION>节点 - 且该节点的第一个紧邻前兄弟节点是
<MULTIPLE>
这个规则会递归遍历整个XML树的所有层级,找到所有符合条件的节点,并且因为模板里没有任何输出语句,这些节点会被直接删除。
- 匹配所有
测试验证
举个简单的输入XML例子:
<ROOT> <MULTIPLE id="1"/> <AGGREGATION>要删除的1</AGGREGATION> <OTHER_NODE>保留内容</OTHER_NODE> <MULTIPLE id="2"/> <AGGREGATION>要删除的2</AGGREGATION> <NESTED> <MULTIPLE id="3"/> <AGGREGATION>要删除的3</AGGREGATION> </NESTED> </ROOT>
经过上面的XSLT转换后,输出会变成:
<ROOT> <MULTIPLE id="1"/> <OTHER_NODE>保留内容</OTHER_NODE> <MULTIPLE id="2"/> <NESTED> <MULTIPLE id="3"/> </NESTED> </ROOT>
可以看到,不管是根层级还是嵌套层级里,所有紧跟在<MULTIPLE>后的<AGGREGATION>都被正确删除了。
内容的提问来源于stack exchange,提问作者wild card
相关产品推荐
相关产品推荐

