如何将 XML 反序列化为 C# 对象而忽略 xmlns?

问题描述 投票:0回答:1

给定以下 XML,我如何将它们反序列化为同一个 C# 对象?版本 1.1 本质上向后兼容 1.0,所以我并不真正关心 xmlns 值,但 C# 不这么认为...

示例版本 1.0:

<?xml version="1.0"?>
<HelloWorld xmlns="https://www.hello.ca/world/1.0">

示例版本1.1:

<?xml version="1.0"?>
<HelloWorld xmlns="https://www.hello.ca/world/1.1">

但是,即使我没有在类中指定名称空间,当调用

Deserialize
时它仍然会抱怨它。代码:

    [Serializable()]
    // other stuff I tried before
    //[XmlType(AnonymousType = true, Namespace = "https://www.hello.ca/world/1.1")]
    //[XmlRoot(Namespace = "https://www.hello.ca/world/1.1", IsNullable = false)]
    [System.ComponentModel.DesignerCategory("code")]
    [XmlType("HelloWorld")]
    public class HelloWorld
    {
       ...
    }

然后在我尝试将其

Deserialize
放入我的对象的代码中:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load("somewhere.xml");

using (XmlReader xr = new XmlNodeReader(xmlDoc))
{
    XmlSerializer xs = new XmlSerializer(typeof(HelloWorld));
    blah = xs.Deserialize(xr) as HelloWorld;
    return blah  != null;
}

我每次遇到的错误是,它不喜欢节点中的

xmlns

InvalidOperationException
 > There is an error in the XML document.
 > <HelloWorld xmlns='https://www.hello.ca/world/1.0'> was not expected.

告诉

XmlSerializer
忽略
xmlns
的正确方法是什么?或者也许可以使该类兼容多个 xmlns?

c# .net xml-namespaces xmldocument xml-deserialization
1个回答
0
投票
using System.Xml.Linq;
using System.Xml.Serialization;

namespace ConsoleApp1;

[Serializable]
public class HelloWorld
{
    // Add other properties that match your XML structure
    public string? Name { get; set; }
}

internal static class Program
{
    private static void Main()
    {
        // Your XML strings
        const string xmlV1 = """
                             <?xml version="1.0"?>
                                <HelloWorld xmlns="https://www.hello.ca/world/1.0">
                                    <Name>Robo1</Name>
                                </HelloWorld>
                             """;
        const string xmlV2 = """
                             <?xml version="1.0"?>
                                <HelloWorld xmlns="https://www.hello.ca/world/1.1">
                                    <Name>Robo2</Name>
                                </HelloWorld>
                             """;

        // Remove namespaces
        var cleanXmlV1 = RemoveNamespaces(xmlV1);
        var cleanXmlV2 = RemoveNamespaces(xmlV2);

        // Deserialize
        var hw1 = DeserializeXml<HelloWorld>(cleanXmlV1);
        var hw2 = DeserializeXml<HelloWorld>(cleanXmlV2);

        // Use the deserialized objects as needed
        Console.WriteLine(hw1.Name);
        Console.WriteLine(hw2.Name);
    }

    private static string RemoveNamespaces(string xml)
    {
        var doc = XDocument.Parse(xml);
        foreach (var node in doc.Descendants())
        {
            // Remove namespace
            node.Name = node.Name.LocalName;
            // Remove attributes that are namespaces
            node.Attributes().Where(a => a.IsNamespaceDeclaration || a.Name.Namespace != XNamespace.None).Remove();
        }

        return doc.ToString();
    }

    private static T DeserializeXml<T>(string xml)
    {
        var serializer = new XmlSerializer(typeof(T));
        using var reader = new StringReader(xml);
        return (T)serializer.Deserialize(reader)!;
    }
}

在这里我创建了一个小例子来忽略名称空间希望这对您有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.