反序列化XML,不包括Xml Root和Namespace删除模式

时间:2014-08-13 08:55:14

标签: c# xml visual-studio serialization

Reference SO Ques

我有2个Xml,我想反序列化为1个类,因为innerxml是相同的,我想删除Scehma即命名空间,并希望在反序列化之前更改rootname。

XML 1

<MyXMLTest1 xsi:schemaLocation="abc1" xmlns:xsi="abc12" xmlns="abc123"> <element1>xml1hi</element1> </MyXMLTest1>

XML 2

<MyXMLTest2 xsi:schemaLocation="abc2" xmlns:xsi="abc23" xmlns="abc234"> <element1>xml1hi</element1> </MyXMLTest2>

[System.Xml.Serialization.XmlRoot("MyXMLTest", IsNullable=true)] public partial class MyXMLTest{ public string element1 {get;set;} }

方式

var xDocument = XDocument.Load(@"myxml.xml"); string myxmlstring = xDocumnet.ToString(); var reader = new StringReader(myxmlstring ); var serializer = new XmlSerializer(typeof(MyXMLTest)); var instance = (MyXMLTest)serializer.Deserialize(reader); //I'm getting error on the last line that <MyXMLTest1 xsi:schemaLocation="abc1" xmlns:xsi="abc12" xmlns="abc123"> was not expected

如何忽略任何上传的Xml的命名空间和根名称?

由于

2 个答案:

答案 0 :(得分:1)

最后我想出了这个问题的解决方案

我做的是

  • 我为每个传入的XML编写了一个更改/覆盖RootName的方法
  • 删除命名空间

然后使用它们。

示例在这里:

希望有人会发现它很有用。

<强>类

[System.Xml.Serialization.XmlRoot("GenericXMLClass", IsNullable=true)]
public partial class GenericXMLClass
{
    public string element1 {get;set;}
}

<强>功能

//RemoveNameSpaces
    public class NamespaceIgnorantXmlTextReader : XmlTextReader
    {
        public NamespaceIgnorantXmlTextReader(System.IO.TextReader reader) : base(reader) { }

        public override string NamespaceURI
        {
            get { return ""; }
        }
    }
    //RemoveNameSpaces
    public class XTWFND : XmlTextWriter
    {
        public XTWFND(System.IO.TextWriter w) : base(w) { Formatting = System.Xml.Formatting.Indented; }
        public override void WriteStartDocument() { }
    }

    //Generate Generic XML Files
    public GenericXMLCLass GenericXmlGenerator()
    {
        var xDocument = XDocument.Load(@"myxml.xml"); 
        string xmlString = xDocumnet.ToString();
        GenericXMLCLass genericXML = new GenericXMLCLass();
        String xml;
            XmlDocument objDoc = new XmlDocument();
            objDoc.LoadXml(xmlString);
            XmlDocument objNewDoc = new XmlDocument();
            XmlElement objNewRoot = objNewDoc.CreateElement("GenericXMLClass");
            objNewDoc.AppendChild(objNewRoot);
            objNewRoot.InnerXml = objDoc.DocumentElement.InnerXml;

            xml = objNewDoc.OuterXml;

                var serializer2 = new XmlSerializer(typeof(GenericXMLClass));
                var reader = new StringReader(xml);
                var instance = (GenericXMLClass)serializer2.Deserialize(new NamespaceIgnorantXmlTextReader(reader));
                genericXML = instance;

        }
        return genericXML;
    }

答案 1 :(得分:0)

鉴于您在此处所做的是反序列化XML 片段,您可能应该查看使用XElement,它可以很好地解析XML,而不管命名空间/根名称等。

var xml = "<MyXMLTest1 xsi:schemaLocation='abc1' xmlns:xsi='abc12' xmlns='abc123'><element1>xml1hi</element1></MyXMLTest1>";
var xmlTest = new MyXMLTest
{
    element1 = XElement.Parse(xml).Value
};
Console.WriteLine(xmlTest.element1); // outputs "xml1hi"
  

......有100个元素

这不是问题,这就是LINQ to XML的美妙之处,您可以查询XML并将每个element1投影为新的MyXMLTest实例

var fragments = from el in XElement.Parse(xml).Elements()
                where el.Name.LocalName == "element1"
                select new MyXMLTest
                {
                    element1 = el.Value
                };

foreach (var f in fragments)
{
    Console.WriteLine(f.element1);
}