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

C#遍历XmlDocument子节点反序列化报路径非法字符问题求解

错误产生原因

抛出"路径中存在非法字符"异常的核心原因是XmlReader.Create的重载匹配错误:

  • element.OuterXml本身已经是字符串类型,不需要额外调用ToString(),它返回的是当前<message>节点的完整XML片段。
  • XmlReader.Create有一个重载接收字符串类型的文件路径参数,当你直接传入XML片段字符串时,方法会默认把这段内容当作磁盘文件路径去尝试读取文件,而XML内容里的<、>、/、空格等字符都是Windows文件路径明令禁止的非法字符,因此直接触发异常。
  • 即使你修正参数传递问题,当前代码还存在序列化映射的隐患:默认的XmlSerializer会将类名作为根节点匹配依据,且需要明确字段和XML节点的映射关系,否则可能出现反序列化后字段值为默认值的问题。
直接基于XmlElement反序列化的实现方案

不需要调用ToString(),也不需要将节点转为XML字符串二次解析,直接使用XmlNodeReader(XmlReader的派生类)读取XmlElement节点即可完成反序列化,性能更高也不会出现参数类型匹配错误,修正后的代码如下:

using System;
using System.Xml;
using System.Xml.Serialization;

class Program
{
    static void Main(string[] args)
    {
        XmlReaderSettings readerSettings = new XmlReaderSettings();
        readerSettings.IgnoreComments = true;

        // 初始化序列化器,显式指定根节点为message,匹配单个<message>节点结构
        XmlSerializer serializer = new XmlSerializer(typeof(Message), new XmlRootAttribute("message"));

        using (XmlReader xmlReader = XmlReader.Create(@"..\..\test.xml", readerSettings))
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(xmlReader);

            foreach (XmlElement element in doc.DocumentElement.ChildNodes)
            {
                Console.WriteLine($"id : {element.SelectSingleNode("id").InnerText}, message : {element.SelectSingleNode("text").InnerText}");
                // 直接传入XmlElement构造XmlNodeReader,无需转字符串
                using (XmlNodeReader nodeReader = new XmlNodeReader(element))
                {
                    Message message = (Message)serializer.Deserialize(nodeReader);
                    // 此处可直接使用反序列化得到的message对象
                }
            }
        }
        Console.ReadLine();
    }
}

public class Message
{
    // 显式映射XML节点和类字段,避免命名/大小写匹配问题
    [XmlElement("id")]
    public int id;
    [XmlElement("text")]
    public string text;
}

补充说明:

  • 所有实现了IDisposable的XML读取相关对象都用using块包裹,可自动释放资源,避免内存泄漏。
  • 如果一定要基于OuterXml的字符串内容反序列化,需要用StringReader包裹字符串后传入,避免触发文件路径的重载,写法为serializer.Deserialize(new StringReader(element.OuterXml)),但该方案需要额外做字符串到内存流的转换,性能弱于直接使用XmlNodeReader的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:06:33