给定以下 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?
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)!;
}
}
在这里我创建了一个小例子来忽略名称空间希望这对您有帮助。