【问题标题】:Deserialize XML excluding XmlRoot and Namespace removing scehma反序列化 XML,不包括 XmlRoot 和命名空间删除架构
【发布时间】:2014-08-13 08:55:14
【问题描述】:

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 的命名空间和根名称?

谢谢

【问题讨论】:

  • MyXMLTest1 和 MyXMLTest2 与类名 MyXMLTest 不匹配。序列化程序可能需要一个 节点。
  • @Dietz 是的,输入 xml 可以有任何名称,所以我想要我自己的名字与 xml 的根名称有关

标签: c# xml visual-studio serialization


【解决方案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;
    }

【讨论】:

    【解决方案2】:

    鉴于您在这里似乎正在反序列化 XML 片段,也许您应该考虑使用 XElement,它在解析 XML 方面做得很好,而与命名空间/根名称等无关。 p>

    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);
    }
    

    【讨论】:

    • 这个 xml 只是一个样本,有 100 个元素,所以我认为提及它们不是一个好主意。另外,我的 xml 和 xmlclass 中有嵌套类
    • @ArijitMukherjee 如果有超过 1 个元素,那么您可以将每个元素投影为一个新的 MyXMLTest 实例(请参阅更新)。
    • James,我的 XMLTest 类也是另一个类对象。喜欢public XMLTEST { public string element1{get;set;} public mymessages _allMessages {get;set;} }希望我自己说清楚。
    • @ArijitMukherjee 抱歉,但我只能继续您在初始问题中提供的信息,您应该在初始问题中披露所有相关信息,并且在给出示例时尽量接近真实代码尽可能 - 否则这只是一个猜谜游戏。无论如何,我认为我的回答已经为您解决了核心问题,剩下的就交给您了。
    • stackoverflow.com/questions/2296305/… 这是我的问题,加上在新版本中我的文件名也发生了变化。无论如何,非常感谢并投入您的时间。
    猜你喜欢
    • 2015-11-03
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2019-01-26
    相关资源
    最近更新 更多