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

如何在xsd.exe生成的C#类中正确使用CDATA?

解决XML序列化中CDATA被自动转义的问题

问题描述

我正在尝试给一个映射为xs:string的字段赋值并写入XML。一开始直接赋值字符串是正常的:

rawdata.data = generatedString;

但当我尝试把内容包裹在CDATA标签里,写成<![CDATA[" + generatedString + "]]>时,最终输出里的CDATA部分被转义成了&amp;lt;![CDATA[这类形式,完全不是预期的CDATA块。

问题根源

你现在用的DataFilesRawdata类里的data字段是普通string类型,默认的XML序列化会把所有特殊字符(比如<、>)都转义,所以你手动加的CDATA标签会被当成普通文本处理,自然就被转义了。

解决方案

要让序列化器识别并生成CDATA块,你需要修改data字段的序列化逻辑,这里有两种实用方法:

方法1:改用XmlCDataSection类型

这是最直接的方式,把data字段的类型换成XmlCDataSection,同时调整对应的序列化属性:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class DataFilesRawdata
{
    private string idField;
    private System.Xml.XmlCDataSection dataField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string ID
    {
        get { return this.idField; }
        set { this.idField = value; }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public System.Xml.XmlCDataSection data
    {
        get { return this.dataField; }
        set { this.dataField = value; }
    }
}

赋值的时候需要通过XmlDocument创建CDATA节点:

XmlDocument doc = new XmlDocument();
rawdata.data = doc.CreateCDataSection(generatedString);

这样序列化时就会自动生成正确的CDATA块,不会被转义。

方法2:自定义序列化逻辑(保留string类型)

如果你不想修改字段类型,可以通过添加辅助属性来控制序列化:
给类新增一个用于序列化的辅助属性,同时把原来的data字段标记为忽略序列化:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class DataFilesRawdata
{
    private string idField;
    private string dataField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string ID
    {
        get { return this.idField; }
        set { this.idField = value; }
    }

    // 用于序列化的辅助属性,生成CDATA
    [System.Xml.Serialization.XmlAnyElementAttribute("data")]
    public XmlNode[] DataCData
    {
        get
        {
            XmlDocument doc = new XmlDocument();
            return new XmlNode[] { doc.CreateCDataSection(dataField) };
        }
        set
        {
            if (value == null || value.Length == 0)
            {
                dataField = null;
                return;
            }
            dataField = value[0].Value;
        }
    }

    // 原来的data字段排除序列化
    [System.Xml.Serialization.XmlIgnoreAttribute]
    public string data
    {
        get { return this.dataField; }
        set { this.dataField = value; }
    }
}

这样你还是可以像之前一样给rawdata.data赋值普通字符串,序列化时会自动转换成CDATA块。

小提示

如果这个类是用xsd工具自动生成的,下次重新生成会覆盖你的修改,建议把自定义逻辑放在单独的部分类文件里,比如新建DataFilesRawdata.Extensions.cs:

public partial class DataFilesRawdata
{
    [System.Xml.Serialization.XmlAnyElementAttribute("data")]
    public XmlNode[] DataCData
    {
        get
        {
            XmlDocument doc = new XmlDocument();
            return new XmlNode[] { doc.CreateCDataSection(dataField) };
        }
        set
        {
            if (value == null || value.Length == 0)
            {
                dataField = null;
                return;
            }
            dataField = value[0].Value;
        }
    }

    [System.Xml.Serialization.XmlIgnoreAttribute]
    public new string data
    {
        get { return this.dataField; }
        set { this.dataField = value; }
    }
}

这样既保留自动生成的代码,又不会丢失自定义逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:23:31