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

如何在XSLT中使用XPath检测XML自闭合标签

XSLT中能否检测自闭合标签?用XPath怎么实现?

首先明确:XSLT和XPath没法直接区分XML里的自闭合标签写法。因为XML解析器处理文档时,会把<entry/>这种自闭合标签,和<entry></entry>这种空的成对标签当成完全一样的空元素节点,解析后的DOM结构没有任何区别,所以XSLT/XPath根本看不到原始写法的差异。

如果你的实际需求是检测是否存在<entry>这个空元素节点(不管它是自闭合还是成对写的),那完全可以用XPath实现,下面针对你给的示例代码修正说明:

补全后的XML示例(原XML存在标签未闭合的语法错误)

<?xml version="1.0" encoding="UTF-8"?>
<catalog>
  <cd>
    <title>1999 Grammy Nominees</title>
    <title>2000 Grammy Nominees</title>
  </cd>
  <cd>
    <entry/>
    <title>2010 Grammy Nominees</title>
    <title>2011 Grammy Nominees</title>
  </cd>
</catalog>

修正后的XSLT代码(原代码存在语法错误和上下文匹配问题)

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <!-- 因用到fo:block元素,将输出模式改为XML,原text模式不适用 -->
  <xsl:output method="xml" indent="yes" />

  <xsl:template match="/catalog">
    <xsl:apply-templates/>
  </xsl:template>

  <!-- 匹配包含entry子节点的cd元素 -->
  <xsl:template match="cd[entry]">
    <xsl:for-each select="title">
      <fo:block background-color="blue">
        <xsl:value-of select="."/>
      </fo:block>
    </xsl:for-each>
  </xsl:template>

  <!-- 匹配不包含entry子节点的cd元素 -->
  <xsl:template match="cd[not(entry)]">
    <xsl:for-each select="title">
      <fo:block background-color="red">
        <xsl:value-of select="."/>
      </fo:block>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

关键逻辑说明

  • cd[entry]:直接匹配所有包含<entry>子节点的<cd>元素,不管<entry>是自闭合还是成对写法。
  • cd[not(entry)]:匹配所有不包含<entry>子节点的<cd>元素。
  • 修正了原代码的语法问题:闭合了未结束的属性和标签,调整了for-each的选择路径(当前上下文已是<cd>,直接选title即可,无需写cd/title)。

特殊情况补充

如果你真的需要区分自闭合标签和成对空标签的原始写法,常规XSLT/XPath做不到——因为XML解析器已经抹平了这种语法差异。这时需要用SAX这类基于事件的XML解析器,抓取原始标签事件来判断,但这已经超出了XSLT的处理范畴。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 22:05:27