C#使用包含XML文本的元素将对象序列化为XML而不进行转义

时间:2018-01-16 13:15:02

标签: c# xml xml-serialization

我搜索并尝试了一些属性,但没有一个适用于我的下面的场景:

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";

我可以覆盖哪些属性或方法使其成为可能吗?

4 个答案:

答案 0 :(得分: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);
}

答案 1 :(得分:0)

不,你不能。这是xml序列化程序的自然和通常行为。序列化程序不必处理XML字符串。所以,它按预期逃脱了xml。

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

我找到了另一种更改类型的方法

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)