使用xsl:copy-of进行XSLT转换时如何保留原父节点而非硬编码?
解决方案
完全可以在使用xsl:copy-of时保留原始父节点,核心思路是先拷贝原始父节点,再将筛选后的子节点插入父节点内即可,针对你给出的场景有两种常用实现方案:
方案1:直接拷贝指定原始父节点
适配你的当前需求,无需硬编码外层节点,直接拷贝原始<library>父节点后插入筛选出的子节点即可:
<?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/library"> <!-- 浅拷贝原始library节点 --> <xsl:copy> <!-- 拷贝library节点的所有属性(如有) --> <xsl:copy-of select="@*" /> <!-- 拷贝筛选后的category子节点 --> <xsl:copy-of select="category[@name='cats']" /> </xsl:copy> </xsl:template> </xsl:stylesheet>
执行后输出结果:
<?xml version="1.0" encoding="UTF-8"?> <library> <category name="cats"> <book> <name>All about cats</name> <author>Someone</author> </book> </category> </library>
方案2:通用身份变换模板(适合复杂筛选场景)
如果你需要保留整个XML的原始层级结构,仅过滤不需要的节点,使用身份变换模板灵活性更高,不需要手动指定父节点层级:
<?xml version="1.0"?> <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> <!-- 过滤掉name不是cats的category节点 --> <xsl:template match="category[@name!='cats']" /> </xsl:stylesheet>
该方案输出结果和方案1完全一致,后续XML结构变动时只需调整过滤规则即可,无需修改父节点拷贝逻辑。
内容的提问来源于stack exchange,提问作者DaveF
相关产品推荐
相关产品推荐

