是否可以有条件地序列化 CDATA?

Is it possible to conditionally serialize CDATA?

我已经看到 solution 让 XmlSerializer 输出 CDATA 部分,但是是否可以根据另一个值有条件地实现这一点?

下面的代码演示了我想要的结果:

enum LogItemType
{
   Default,
   Xml
}

class LogItem
{
   public string Name { get; set; }
   public LogItemType Type { get; set; }
   [XmlIgnore]
   public string Value { get; set; }
   public XmlCDataSection ValueString
   {
      if(Type == LogItemType.Xml)
         // return CDATA
      else
         // return string (not CDATA)
   }
}

ValueString 属性 的 return 类型更改为 XmlCharacterData, which is the base class for XmlText and XmlCDataSection。然后 return 一个或另一个取决于你的状态 Type 属性:

public class LogItem
{
    public string Name { get; set; }
    public LogItemType Type { get; set; }

    [XmlIgnore]
    public string Value { get; set; }

    [XmlElement("Value")]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public XmlCharacterData ValueString
    {
        get
        {
            if (Value == null)
                return null;
            else if (Type == LogItemType.Xml)
                // return CDATA
                return new XmlDocument().CreateCDataSection(Value);
            else
                // return string (not CDATA)
                return new XmlDocument().CreateTextNode(Value);
        }
        set
        {
            Value = value == null ? null : value.Value;
        }
    }
}

输出将是:

<LogItem>
    <Name>test</Name>
    <Type>Default</Type>
    <Value>this is a test string</Value>
</LogItem>

<LogItem>
    <Name>test</Name>
    <Type>Xml</Type>
    <Value><![CDATA[this is a test string]]></Value>
</LogItem>

或者,如果您希望 Value 文本成为 LogItem 本身的值(而不是嵌套元素的值),您可以这样做:

    [XmlText]
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
    public XmlNode [] ValueString
    {
        get
        {
            if (Value == null)
                return null;
            else if (Type == LogItemType.Xml)
                // return CDATA
                return new XmlNode[] { new XmlDocument().CreateCDataSection(Value) };
            else
                // return string (not CDATA)
                return new XmlNode[] { new XmlDocument().CreateTextNode(Value) };
        }
        set
        {
            Value = value == null ? null : string.Concat(value.Select(n => n.Value).ToArray());
        }
    }

(请注意,数组 return 不是单个项目。XmlSerializer 似乎需要这个。)