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

如何去除Tally XML科目导出响应中的特殊字符

解决C#反序列化Tally XML时的0x04无效字符问题

反序列化Tally导出的科目XML响应时,出现XmlException: '', 十六进制值0x04是无效字符错误,根源是<PARENT>元素中包含&#4;(对应ASCII控制字符0x04)——这类控制字符不符合XML规范,导致反序列化失败。以下是几种可行的解决方法:

方法一:预处理XML字符串,过滤无效控制字符

先读取响应内容为字符串,通过正则表达式移除XML不允许的控制字符(仅保留制表符、换行、回车),再进行反序列化:

var responseContent = await response.Content.ReadAsStringAsync();
// 过滤XML无效控制字符(0x00-0x08、0x0B、0x0C、0x0E-0x1F)
var cleanedContent = Regex.Replace(responseContent, @"[\x00-\x08\x0B\x0C\x0E-\x1F]", string.Empty);

// 使用清理后的内容创建流反序列化
using var stream = new MemoryStream(Encoding.UTF8.GetBytes(cleanedContent));
XmlSerializer serializer = new XmlSerializer(typeof(Ledgers));
var ledgers = (Ledgers?)serializer.Deserialize(stream);

方法二:自定义XmlTextReader处理无效字符

创建继承自XmlTextReader的自定义阅读器,在读取元素文本时过滤无效字符,避免修改整个XML结构:

public class CleanXmlReader : XmlTextReader
{
    public CleanXmlReader(Stream stream) : base(stream) { }

    public override string ReadString()
    {
        var rawValue = base.ReadString();
        // 移除文本中的无效控制字符
        return Regex.Replace(rawValue, @"[\x00-\x08\x0B\x0C\x0E-\x1F]", string.Empty);
    }
}

使用自定义阅读器反序列化:

using var stream = await response.Content.ReadAsStreamAsync();
using var cleanReader = new CleanXmlReader(stream);
XmlSerializer serializer = new XmlSerializer(typeof(Ledgers));
var ledgers = (Ledgers?)serializer.Deserialize(cleanReader);

方法三:从源头修改Tally导出配置(优先推荐)

如果有权限调整Tally的导出TDL,可以直接在获取Parent字段时过滤特殊字符,从根源避免无效字符输出:

<FIELD ISMODIFY="NO" ISFIXED="NO" ISINITIALIZE="NO" ISOPTION="NO" ISINTERNAL="NO" NAME="CA_PARENT">
    <SET>$PARENT</SET>
    <!-- 添加控制字符过滤逻辑 -->
    <FORMAT>$$Str:Replace($PARENT, Chr(4), "")</FORMAT>
    <XMLTAG>PARENT</XMLTAG>
</FIELD>

总结

  • 若能修改Tally的TDL配置,优先选择方法三,从源头解决问题;
  • 无法修改导出配置时,方法一和方法二均可有效过滤无效字符,确保反序列化正常执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:20:06