You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MSXML6+XSLT过滤XML节点时,如何保留自闭合标签格式

如何让XSLT处理后保留XML自闭合标签

问题背景

有这样一段初始XML:

<osmChange>
    <way id="304298875">
      <nd ref="3088293757"/>
      <tag k="name" v="Tizard Place"/>
    </way>
    <way id="305295788">
      <nd ref="12232709336"/>
      <nd ref="3099014747"/>
      <tag k="building" v="train_station"/>
    </way>
</osmChange>

用MSXML6的transformNode命令执行下面的XSLT,目的是过滤掉所有<nd>节点:

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="nd"/> 

结果确实过滤掉了<nd>,但剩下的<tag>节点被改成了非自闭合的格式:

<way id="305295788">    
<tag k="building" v="train_station">
</tag>
</way>

需要修改XSLT,让<tag>保持<tag k="..." v="..."/>这种自闭合的形式。

可行解决方案

方案1:修改XSLT,添加输出配置并显式处理空元素

在XSLT开头加上输出声明,同时给空元素(没有子节点的元素)单独写模板,强制输出自闭合标签:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 配置XML输出格式 -->
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />

    <!-- 基础的复制模板 -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!-- 过滤nd节点 -->
    <xsl:template match="nd"/>

    <!-- 针对没有子节点的元素,输出自闭合标签 -->
    <xsl:template match="*[not(node())]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这个方案通过专门匹配空元素的模板,告诉XSLT处理器:只要元素没有子节点,就输出成自闭合的形式,而不是展开成开始+结束标签。

方案2:改用transformNodeToObject配合XMLWriter控制输出

如果方案1效果不理想,可以换用MSXML的transformNodeToObject方法,结合XMLWriter来精确控制输出格式:

  1. 先创建XMLWriter并设置参数:
Set xmlWriter = CreateObject("MSXML2.MXXMLWriter.6.0")
xmlWriter.indent = True ' 保持缩进格式
xmlWriter.omitXMLDeclaration = True ' 不需要XML声明
xmlWriter.output = Response ' 这里可以替换成你需要的输出目标,比如文件流
  1. 创建SAX处理器并关联XMLWriter,再执行转换:
Set saxReader = CreateObject("MSXML2.SAXXMLReader.6.0")
saxReader.contentHandler = xmlWriter
' 替换成你的XML文档和XSLT文档对象
saxReader.parse(xmlDoc.transformNodeToObject(xsltDoc, xmlWriter))

XMLWriter可以强制空元素以自闭合标签的形式输出,避免transformNode默认的序列化行为。

内容的提问来源于stack exchange,提问作者DaveF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 06:25:19