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

如何将内层元素状态传递到外层?XSLT技术实现问询

XSLT 根据内层元素状态生成外层错误标记解决方案

需求背景

基于此前Stack Overflow问题《XSLT: How to skip element when specific inner child element is missing?》的内容模型,需实现以下逻辑:

  • 当perf_data下的所有sample元素均不含value子元素时,在perf_data层级生成<Error>1</Error>
  • 否则生成<Error>0</Error>
    已完成忽略无效sample的模板编写,但因XSLT变量不可变特性,无法通过计数器实现外层判断逻辑,需解决方案。

输入示例

无效示例(Bad Sample)

<?xml version="1.0" encoding="utf-8"?>
<MonitoringOutput id="id-3150" version="0.2">
  <description>snmp_netif-1.out</description>
  <exit_code>0</exit_code>
  <status_string>Previous state not found, U octets/s in [delta 0s], U octets/s out [delta 0s]</status_string>
  <perf_string> in=U;;;0 out=U;;;0</perf_string>
  <perf_data count="2">
    <sample label="in">
      <label>in</label>
      <range min="0"/>
    </sample>
    <sample label="out">
      <label>out</label>
      <range min="0"/>
    </sample>
  </perf_data>
</MonitoringOutput>

有效示例(Good Sample)

<?xml version="1.0" encoding="utf-8"?>
<MonitoringOutput id="id-3160" version="0.2">
  <description>snmp_netif-2.out</description>
  <exit_code>0</exit_code>
  <status_string>bond0</status_string>
  <info_string>1560.23 octets/s in [delta 10s], 350.921 octets/s out [delta 10s]</info_string>
  <perf_string> in=1560.23B;;;0 out=350.921B;;;0</perf_string>
  <perf_data count="2">
    <sample label="in">
      <label>in</label>
      <value unit="B">1560.23</value>
      <unit>B</unit>
      <range min="0"/>
    </sample>
    <sample label="out">
      <label>out</label>
      <value unit="B">350.921</value>
      <unit>B</unit>
      <range min="0"/>
    </sample>
  </perf_data>
</MonitoringOutput>

解决方案

无需使用计数器,利用XPath节点存在性判断即可实现逻辑,分XSLT版本给出实现:

XSLT 1.0 实现

核心思路:通过not(sample/value)判断当前perf_data下是否没有任何sample包含value元素(若存在至少一个sample有value,该表达式返回false)。

完整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>

  <!-- 处理perf_data节点 -->
  <xsl:template match="perf_data">
    <xsl:copy>
      <!-- 复制原有属性 -->
      <xsl:apply-templates select="@*"/>
      <!-- 生成Error标记 -->
      <Error>
        <xsl:choose>
          <!-- 所有sample都没有value元素 -->
          <xsl:when test="not(sample/value)">1</xsl:when>
          <!-- 至少一个sample有value元素 -->
          <xsl:otherwise>0</xsl:otherwise>
        </xsl:choose>
      </Error>
      <!-- 应用原有sample处理模板(忽略无效sample) -->
      <xsl:apply-templates select="sample[value]"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

XSLT 2.0+ 实现

XSLT 2.0及以上支持every表达式,逻辑更直观:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.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>

  <!-- 处理perf_data节点 -->
  <xsl:template match="perf_data">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <Error>
        <xsl:value-of select="if (every $s in sample satisfies not($s/value)) then 1 else 0"/>
      </Error>
      <xsl:apply-templates select="sample[value]"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

输出效果

  • 无效示例处理后,perf_data节点下会生成<Error>1</Error>,且无sample子节点(所有无效sample已被过滤)
  • 有效示例处理后,perf_data节点下生成<Error>0</Error>,并保留含value的sample节点

内容的提问来源于stack exchange,提问作者U. Windl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:16:01