如何将CDATA与xsd.exe生成的C#类一起使用?

时间:2018-05-16 10:49:52

标签: c# xml cdata xsd.exe

问题

我正在尝试填写一个映射到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;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

使用 XmlCDataSection

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

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

分配:

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

答案 1 :(得分: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