如何基于配置文件条件通过XSLT删除XML中的指定行
实现方案
前提:文件结构示例
首先确认两个文件的基础结构和你描述一致,方便后续代码适配:
<!-- config.xml 示例结构 --> <config> <values> <s1>yes</s1> <s2>no</s2> <s3>yes</s3> <s4>no</s4> </values> </config>
<!-- my_input.xml 示例结构 --> <root xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="s1.xml"/> <xi:include href="s2.xml"/> <otherNode>其他不需要修改的内容</otherNode> <xi:include href="s3.xml"/> <xi:include href="s4.xml"/> </root>
完整XSLT实现代码
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xi="http://www.w3.org/2001/XInclude" exclude-result-prefixes="xi"> <!-- 读取外部config.xml,存储配置节点到变量避免重复读取 --> <xsl:variable name="config" select="document('config.xml')/config/values"/> <!-- 身份模板:默认复制所有节点、属性到输出,不做修改 --> <xsl:template match="@* | node()"> <xsl:copy> <xsl:apply-templates select="@* | node()"/> </xsl:copy> </xsl:template> <!-- 匹配需要删除的xi:include节点:对应配置为no时不输出,相当于删除 --> <xsl:template match="xi:include[ $config/*[name() = substring-before(current()/@href, '.xml')] = 'no' ]"/> </xsl:stylesheet>
逻辑说明
document()是XSLT内置函数,支持读取外部XML文件,这里直接加载config.xml的values节点存为变量,调用效率更高。- 身份模板是通用转换规则,保证除了你要过滤的xi:include节点外,输入文件的其他所有内容都会原封不动输出。
- 过滤规则的匹配逻辑:先提取当前xi:include节点href属性去掉
.xml后缀的字符串(也就是s1/s2/s3/s4),再到配置变量中找同名节点的取值,如果取值为no,该模板就不会输出任何内容,直接过滤掉对应节点。
注意事项
- 如果config.xml不在XSLT执行的工作目录下,修改
document('config.xml')里的路径即可,支持相对路径和绝对路径。 - 要保证XSLT中声明的xi命名空间和你的my_input.xml里的xi命名空间完全一致,否则会匹配不到对应节点。
内容的提问来源于stack exchange,提问作者Kilsoi Samuel
相关产品推荐
相关产品推荐

