【问题标题】:How can I use CDATA with generated C# classes from xsd.exe?如何将 CDATA 与从 xsd.exe 生成的 C# 类一起使用?
【发布时间】:2018-10-26 09:25:15
【问题描述】:

问题

我正在尝试填写映射到 xs:string 的部分并将其写入 XML。

我把这个值的生成代码放在了这篇文章的底部,因为它有点长。

之前我只是为它分配了字符串值。

rawdata.data = generatedString;

但是当我尝试这个时。

rawdata.data = "<![CDATA[" + generatedString + "]]>";

无论如何,最终的输出都会格式化 CDATA 部分。

&lt;![CDATA[

有什么方法可以避免这种情况的发生,让 CDATA 显示其应有的样子?

额外信息

为此字段生成的代码。

/// <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;
        }
    }

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

【问题讨论】:

    标签: c# xml cdata xsd.exe


    【解决方案1】:

    @SeM 的答案是我认为根据 Microsoft 如何构建 XML 序列化程序的最正确的解决方案,但由于我需要从 XSD 重新生成类相对经常我认为最好是尝试寻找其他解决方案,而不是在每次构建后手动编辑生成的类。

    在这种情况下,我发现我可以覆盖 XmlSerializer,而不是修改生成的类,以便在遇到 CDATA 内容时能够处理它。

    当然,这仅在 CDATA 位于元素的最开始和最结束时才有效。在这方面它适合我的用例,但不能普遍实现所有用例。

    using (var fileStream = new System.IO.FileStream(tempFilePath,FileMode.Create))
    {                
        var xmlwriter = new CustomXmlTextWriter(fileStream);
        xmls.Serialize(xmlwriter, contents, ns);
    }
    

    还有自定义编写器。

    public class CustomXmlTextWriter : XmlTextWriter
    {
    
        //... constructor if you need it
    
        public override void WriteString(string text)
        {
            if (text.StartsWith("<![CDATA[") && text.EndsWith("]]>"))
            {
                base.WriteRaw(text);
                return;
            }
            base.WriteString(text);
        }
    
    }
    

    看起来这与微软采取的路线一致。

    https://referencesource.microsoft.com/#SMDiagnostics/System/ServiceModel/Diagnostics/PlainXmlWriter.cs,137

    【讨论】:

    • 不错的解决方案,真的。
    【解决方案2】:

    为此使用 XmlCDataSection

    [XmlElement("data")]
    public System.Xml.XmlCDataSection Data { get; set; }
    

    如果您序列化您的对象,它将自动在您的 xml 中创建 CData 部分。

    分配它:

    rawdata.data = System.Xml.XmlDocument().CreateCDataSection(generatedString);
    

    【讨论】:

    • 我认为这会起作用,尽管它需要修改自动生成的类。我想知道我是否可以利用大多数生成的类是partial 类这一事实来在整个重新生成过程中保持我的更改。
    • 它是由什么自动生成的?
    • Microsoft SDK 中的 XML 架构定义工具 xsd.exe 工具。 docs.microsoft.com/en-us/dotnet/standard/serialization/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    • 2011-05-18
    • 2020-06-19
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多