【问题标题】:C# serialize object to XML with element containing XML text without escapingC# 使用包含 XML 文本的元素将对象序列化为 XML 而不转义
【发布时间】:2018-01-16 13:15:01
【问题描述】:

我搜索并尝试了一些属性,但它们都不适用于我的以下场景:

public class ObjSer
{
    [XmlElement("Name")]        
    public string Name
    {
        get; set;
    }
}

//Code to serialize
var obj = new ObjSer();
obj.Name = "<tag1>Value</tag1>";
        var stringwriter = new System.IO.StringWriter();
        System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
        serializer.Serialize(stringwriter, obj);

输出如下:

<ObjSer><Name>&lt;tag1&gt;Value&lt;/tag1&gt;</Name></ObjSer>

但我需要输出为:

<ObjSer><Name><tag1>Value</tag1></Name></ObjSer>

场景2:在某些情况下我需要设置:

obj.Name = "Value";

是否有任何属性或方法我可以重写以使其成为可能?

【问题讨论】:

    标签: c# xml xml-serialization


    【解决方案1】:

    您不能使用默认序列化程序。 XmlSerializer 在序列化过程中对所有值进行编码。

    如果你想让你的成员持有 xml 值,它必须是 XmlElement。以下是你如何完成它

    public class ObjSer
    {
        [XmlElement("Name")]
        public XmlElement Name
        {
            get; set;
        }
    }
    
    var obj = new ObjSer();
    
    // <-- load xml
    var doc = new XmlDocument();
    doc.LoadXml("<tag1>Value</tag1>");
    obj.Name = doc.DocumentElement;
    // --> assign the element
    
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
    serializer.Serialize(Console.Out, obj);
    

    输出:

    <?xml version="1.0" encoding="IBM437"?>
    <ObjSer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Name>
        <tag1>Value</tag1>
      </Name>
    </ObjSer>
    

    更新:

    如果你想使用 XElement 而不是 XmlElement,这里是如何做的示例

    public class ObjSer
    {
        [XmlElement("Name")]
        public XElement Name
        {
            get; set;
        }
    }
    
    static void Main(string[] args)
    {
        //Code to serialize
        var obj = new ObjSer();
        obj.Name = XDocument.Parse("<tag1>Value</tag1>").Document.FirstNode as XElement;
        System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(obj.GetType());
        serializer.Serialize(Console.Out, obj);
    }
    

    【讨论】:

    • 我建议使用XElement 而不是XmlElement
    • 这样也行。
    • 添加了场景 2,因为来自源的一些值不包含同一字段的标签。建议的方法将引发错误,因为它不会形成 XML 根。感谢您的努力。
    【解决方案2】:

    不,你不能。这是 xml 序列化程序的自然和常见行为。序列化程序不必在 XML 字符串中进行处理。因此,它按预期转义了 xml。

    您应该在反序列化时再次解码转义字符串。

    如果您想在 XML 中动态添加元素,我建议您使用Linq to XML,您可以轻松创建tag1 或其他类型的元素。

    【讨论】:

      【解决方案3】:

      我建议序列化为 XDocument,然后将其转换为字符串并手动取消转义所需部分并将其写入文件。我会说这会给您带来最少的头痛,它不应该超过几行代码。如果需要,我可以提供一些代码示例。

      【讨论】:

        【解决方案4】:

        我发现了另一种改变类型的方法

        public class NameNode
        {
            public string tag1
            {
                get; set;
            }
        
            [XmlText]
            public string Value
            {
                get; set;
            }
        
        }
        public class ObjSer
        {
            [XmlElement("Name")]        
            public NameNode Name
            {
                get; set;
            }
        }
        

        要设置名称的值:

                    var obj = new ObjSer();
                    var valueToSet = "<tag1>Value</tag1>";
                    //or var valueToSet = "Value";
                    //With XML tag:
                    if (valueToSet.Contains("</"))
                    {
                        var doc = new XmlDocument();
        
                        doc.LoadXml(valueToSet);
        
                        obj.Name.tag1 = doc.InnerText;
                    }
                    else //Without XML Tags
                    {
                        obj.Name.Value = senderRecipient.Name;
                    }
        

        此解决方案适用于这两种情况,但有局限性。它仅适用于预定义的标签(例如 tag1)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-15
          • 1970-01-01
          • 2016-09-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多