Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以让XmlSerializer在反序列化时忽略名称空间吗?_C#_.net_Serialization_Xml Serialization - Fatal编程技术网

C# 我可以让XmlSerializer在反序列化时忽略名称空间吗?

C# 我可以让XmlSerializer在反序列化时忽略名称空间吗?,c#,.net,serialization,xml-serialization,C#,.net,Serialization,Xml Serialization,我是否可以让XmlSerializer在反序列化时忽略名称空间(xmlns属性),这样无论是否添加属性,甚至属性是否是假的?我知道源代码总是可信的,所以我不关心xmlns属性。为什么要让XmlSerializer忘记XML是如何工作的?XML的一个事实是,具有相同名称但不同名称空间的两个元素是不同的元素 如果要处理没有名称空间的XML,则应该对其进行预处理以删除名称空间,然后将其传递给序列化程序。是的,可以告诉XmlSerializer在反序列化过程中忽略名称空间 定义忽略名称空间的XmlTex

我是否可以让XmlSerializer在反序列化时忽略名称空间(xmlns属性),这样无论是否添加属性,甚至属性是否是假的?我知道源代码总是可信的,所以我不关心xmlns属性。

为什么要让XmlSerializer忘记XML是如何工作的?XML的一个事实是,具有相同名称但不同名称空间的两个元素是不同的元素


如果要处理没有名称空间的XML,则应该对其进行预处理以删除名称空间,然后将其传递给序列化程序。

是的,可以告诉XmlSerializer在反序列化过程中忽略名称空间

定义忽略名称空间的XmlTextReader。像这样:

// helper class to ignore namespaces when de-serializing
public class NamespaceIgnorantXmlTextReader : XmlTextReader
{
    public NamespaceIgnorantXmlTextReader(System.IO.TextReader reader): base(reader) { }

    public override string NamespaceURI
    {
        get { return ""; }
    }
}

// helper class to omit XML decl at start of document when serializing
public class XTWFND  : XmlTextWriter {
    public XTWFND (System.IO.TextWriter w) : base(w) { Formatting= System.Xml.Formatting.Indented;}
    public override void WriteStartDocument () { }
}
以下是如何使用该文本阅读器反序列化的示例:

public class MyType1 
{
    public string Label
    {
        set {  _Label= value; } 
        get { return _Label; } 
    }

    private int _Epoch;
    public int Epoch
    {
        set {  _Epoch= value; } 
        get { return _Epoch; } 
    }        
}



    String RawXml_WithNamespaces = @"
      <MyType1 xmlns='urn:booboo-dee-doo'>
        <Label>This document has namespaces on its elements</Label>
        <Epoch xmlns='urn:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'>0</Epoch>
      </MyType1>";


    System.IO.StringReader sr;
    sr= new System.IO.StringReader(RawXml_WithNamespaces);
    var s1 = new XmlSerializer(typeof(MyType1));
    var o1= (MyType1) s1.Deserialize(new NamespaceIgnorantXmlTextReader(sr));
    System.Console.WriteLine("\n\nDe-serialized, then serialized again:\n");
    XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
    ns.Add("urn", "booboo-dee-doo");
    s1.Serialize(new XTWFND(System.Console.Out), o1, ns);
    Console.WriteLine("\n\n");
公共类MyType1
{
公共字符串标签
{
设置{u Label=value;}
获取{return\u Label;}
}
私人国际时代;
公共信息时代
{
设置{u Epoch=value;}
获取{return\u Epoch;}
}        
}
字符串RawXml_,名称空间=@”
此文档的元素上有名称空间
0
";
System.IO.StringReader sr;
sr=新的System.IO.StringReader(带名称空间的RawXml_);
var s1=新的XmlSerializer(typeof(MyType1));
var o1=(MyType1)s1.反序列化(新名称空间信号器XMLTextReader(sr));
System.Console.WriteLine(“\n\n先序列化,然后再序列化:\n”);
XmlSerializerNamespaces ns=新的XmlSerializerNamespaces();
加上(“瓮”、“booboodeo”);
s1.序列化(新的XTWFND(System.Console.Out),o1,ns);
Console.WriteLine(“\n\n”);
结果是这样的:

    <MyType1>
      <Label>This document has namespaces on its elements</Label>
      <Epoch>0</Epoch>
    </MyType1>

此文档的元素上有名称空间
0

通过使用XmlSerializer反序列化从xml而不是从流中读取来解决这个问题。这样,在反序列化xml之前,使用正则表达式从xml中删除xsi:type。这是一个跨平台的可移植类库,所以没有很多其他选择:(。在此之后,反序列化似乎可以正常工作

下面的代码可能会有所帮助

public static TClass Deserialize<TClass>(string xml) where TClass : class, new()
{
    var tClass = new TClass();

    xml = RemoveTypeTagFromXml(xml);

    var xmlSerializer = new XmlSerializer(typeof(TClass));
    using (TextReader textReader = new StringReader(xml))
    {
        tClass = (TClass)xmlSerializer.Deserialize(textReader);
    }
    return tClass;
}

public static string RemoveTypeTagFromXml(string xml)
{
    if (!string.IsNullOrEmpty(xml) && xml.Contains("xsi:type"))
    {
        xml = Regex.Replace(xml, @"\s+xsi:type=""\w+""", "");
    }
    return xml;
}
publicstatictclass反序列化(字符串xml),其中TClass:class,new()
{
var tClass=new tClass();
xml=从xml(xml)中移除TypeTagFromXML;
var xmlSerializer=新的xmlSerializer(typeof(TClass));
使用(TextReader TextReader=new StringReader(xml))
{
tClass=(tClass)xmlSerializer.Deserialize(textReader);
}
返回tClass;
}
公共静态字符串RemoveTypeTagFromXml(字符串xml)
{
if(!string.IsNullOrEmpty(xml)&&xml.Contains(“xsi:type”))
{
xml=Regex.Replace(xml,@“\s+xsi:type=”“\w+”,“”);
}
返回xml;
}

这并没有忽略名称空间,而是期望它。我曾尝试做与您相同的事情,但后来我使用XSD添加了验证,现在需要名称空间。因此,这里是我过去期望的名称空间。

如果您不期望名称空间,但输入有名称空间,则可以设置

名称空间=false


在您的XmlTextReader上。

Exdented Wolfgang Grinfeld回答(无异常处理):


请注意,这正是我的意思。你不是告诉XmlSerializer忽略名称空间,而是给它没有名称空间的XML。??我不明白。我给它的XML元素上有名称空间。代码反序列化(读取)XML文档并忽略了名称空间。请小心,如果覆盖
NamespaceURI
,它不仅会影响所有元素,还会影响属性。有时,这会导致反序列化程序忽略属性,而这些属性会将它们全部设置为null。显然忽略名称空间存在缺陷。对于元素,您也可以这样说ents-如果反序列化程序需要一个名称空间限定的元素,并且在没有名称空间的情况下找到一个元素,那么它将不会在反序列化实例中设置关联属性。这些只是规则。在我给出的示例中它起作用,因为所有元素都没有名称空间。John,你说的是真的,但是,有时你会得到“xml”数据来自那些认为xml只是一个开头标记后的格式良好的数据的人。.使用尖括号的结束标记样式;他们完全不知道整个名称空间的概念;我猜NotDan是那些需要使用这种人提供的xml数据的可怜人之一。我经历过“说不就行”“,否则就没有XML标准。@约翰:有时你不得不挑起争端。“只要对一些相对琐碎的事情说不”,客户就会说“如果你做不到,那么还有很多其他人可以做到。宝贝,祝你好运!”。我们可以指出潜在的问题,但最终这是他们的硬币和决定。如果我们想保住他们的生意,我们必须尊重这一决定并努力解决它。@simon这种态度是导致问题持续存在的原因,即使是七年后。我应该说“没有,但我们很乐意帮助您学习生成有效的XML“@John,是的,除非你必须与zml接口,否则你无法控制。请告诉UPS、FedEx和USPS修复他们损坏的Web服务。我很乐意。你可以将名称空间通知XmlSerializer,因此不需要从XML中删除:XmlSerializer serializer=new XmlSerializer(typeof(t),elementXml.GetDefaultNamespace().NamespaceName);返回(T)序列化程序。反序列化(elementXml.CreateReader());
public static Message Convert(XmlDocument doc)
{
    Message obj;
    using (TextReader textReader = new StringReader(doc.OuterXml))
    {
        using (XmlTextReader reader = new XmlTextReader(textReader))
        {
            reader.Namespaces = false;
            XmlSerializer serializer = new XmlSerializer(typeof(Message));
            obj = (Message)serializer.Deserialize(reader);
        }
    }

    return obj;
}