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

通过XSL修改XML属性时Terraform报xdr解码错误如何排查

问题描述

现有XML片段如下:

</disk>
<disk type='file' device='cdrom'>
  <driver name='qemu' type='raw'/>
  <source file='discovery.iso' index='1'/>
  <backingStore/>
  <target dev='hdd' bus='ide'/>
  <readonly/>
  <alias name='ide0-1-1'/>
  <address type='drive' controller='0' bus='1' target='0' unit='1'/>
</disk>

需求为将XML中target节点的bus属性值从ide修改为scsi。
使用的XSL转换模板运行时抛出异常,模板内容如下:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="disk[@type='file']/target">
    <xsl:copy>
      <xsl:attribute name="bus">scsi</xsl:attribute>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Terraform运行时错误信息:

xdr:DecodeUint: EOF while decoding 4 bytes - read
错误原因

XSL模板存在核心逻辑错误:
自定义target节点匹配模板时,先手动创建了值为scsi的bus属性,后续执行<xsl:apply-templates select="@*|node()"/>时又将原节点自带的bus="ide"属性复制到目标节点,最终生成的target节点存在两个同名bus属性,属于非法XML结构。Terraform的libvirt provider底层依赖libvirt解析XML,遇到非法结构时就会抛出这类EOF解码错误。
另外提供的XML片段开头存在孤立的</disk>闭合标签,如果是实际使用的XML内容,需要先删除该无效标签,保证XML本身格式合法。

修正方法

调整target节点的模板逻辑,复制原属性时排除原有bus属性即可,修正后的完整XSL如下:

<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <!-- 通用复制模板,原样透传所有未匹配自定义规则的节点、属性 -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="disk[@type='file']/target">
    <xsl:copy>
      <!-- 写入修改后的bus属性 -->
      <xsl:attribute name="bus">scsi</xsl:attribute>
      <!-- 复制除原有bus属性外的其他所有属性、子节点 -->
      <xsl:apply-templates select="@*[name()!='bus']|node()"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

转换后生成的target节点符合规范,结构如下:

<target dev='hdd' bus='scsi'/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 21:36:42