标签: xmlserializer

当使用泛型类型约束时,XmlSerializer抛出InvalidOperationException

当我尝试运行以下代码(两个分离的程序集)时

ClassLibrary.cs

public interface ITest
{
}
Run Code Online (Sandbox Code Playgroud)

Program.cs中

using System;

public class TestClass
{
    public void Test<T>(T x) where T : ITest { }
}

static class Program
{ 
    static void Main(string[] args)         
    {
        new System.Xml.Serialization.XmlSerializer(typeof(TestClass));
    }
}
Run Code Online (Sandbox Code Playgroud)

使用以下命令在Windows 7 64位中编译:

c:\ Windows\Microsoft.NET\Framework\v2.0.50727\csc/target:library ClassLibrary.cs

c:\ Windows\Microsoft.NET\Framework\v2.0.50727\csc /reference:ClassLibrary.dll Program.cs

我得到了这个例外:

System.InvalidOperationException:无法生成临时类(result = 1).错误CS0012:类型ITest在未引用的程序集中定义.您必须添加对程序集ClassLibrary的引用,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null hinzu.

在System.Xml.Serialization.Compiler.Compile(大会父,串NS,XmlSerializerCompilerParameters xmlParameters,证据证据)
在System.Xml.Serialization.TempAssembly.GenerateAssembly(XmlMapping [] xmlMappings,类型[]类型,字符串defaultNamespace,证据证据, XmlSerializerCompilerParameters参数,装配组件,哈希表组件)在System.Xml.Serialization.TempAssembly..ctor(XmlMapping [] xmlMappings,类型[]类型,字符串defaultNamespace,字符串位置,证据证据)在System.Xml.Serialization.XmlSerializer.GenerateTempAssembly在Program.Main(String [] args)的System.Xml.Serialization.XmlSerializer..ctor(Type type,String defaultNamespace)中的(XmlMapping xmlMapping,Type type,String defaultNamespace)

TestClass移除where T:ITest或根本不使用泛型(例如使用 …

.net c# generics xmlserializer

7
推荐指数
1
解决办法
3790
查看次数

反序列化XML时忽略指定的编码

我试图通过套接字读取从外部接口收到的一些XML.问题是XML头中的编码指定错误(它表示iso-8859-1,但它是utf-16BE).据记载,编码是utf-16BE,但显然他们忘记设置正确的编码.

要在反序列化时忽略编码,我使用如下的StringReader:

    private static T DeserializeXmlData<T>(byte[] xmlData)
    {
        var xmlString = Encoding.BigEndianUnicode.GetString(xmlData);
        using (var reader = new StringReader(xmlString))
        {
            reader.ReadLine(); // Eat header line
            using (var xmlReader = XmlReader.Create(reader))
            {
                var serializer = new XmlSerializer(typeof(T));
                return (T)serializer.Deserialize(xmlReader);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

以上实际上工作正常,但我不喜欢通过调用ReadLine跳过标题行的部分.是否有一种不那么脆弱的方法来绕过XML标头中指定的编码?

使用StreamReader解决方案

通过使用StreamReader,我可以覆盖XML头中指定的编码.指定XmlReaderSettings.IgnoreProcessingInstructions与否没有任何区别.有趣的是,如果StreamReader找到unicode字节顺序标记,则忽略指定的编码.

回顾一下:

  • 如果使用TextReader初始化XmlReader,则忽略XML标头编码.
  • 如果使用StringReader,则如果存在unicode字节顺序标记,则XmlReader将失败.
  • 如果使用StreamReader,则unicode字节顺序标记将覆盖StreamReader编码.
  • 使用TextReader时,XmlReaderSettings.IgnoreProcessingInstructions = true没有区别.

总之,最强大的解决方案似乎是使用StreamReader,因为它使用字节顺序标记(如果存在).

    private static T DeserializeXmlData<T>(byte[] xmlData)
    {
        using (var xmlDataStream = new MemoryStream(xmlData))
        {
            using (var reader = new StreamReader(xmlDataStream, Encoding.BigEndianUnicode))
            {
                using (var xmlReader = XmlReader.Create(reader))
                {
                    var serializer …
Run Code Online (Sandbox Code Playgroud)

.net xml xmlserializer stringreader

7
推荐指数
1
解决办法
2946
查看次数

序列化具有相同类型名称的多态List

我有一个对象,我正在尝试序列化为XML.在此对象内部是泛型类型(抽象类)的列表.此列表中的每个项可以是不同的类,但所有项都继承自抽象基类:

public abstract class animal
{
  public string type { get; set; }
}
public class cat:animal
{
  public string size { get; set; }
  public string furColor { get; set; }
}
public class fish:animal
{
  public string size { get; set; }
  public string scaleColor { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

当我序列化列表时,我希望它看起来像这样:

<animal type="cat">
  <size>medium</size>
  <furColor>black</furColor>
</animal>
<animal type="fish">
  <size>small</size>
  <scaleColor>silver</scaleColor>
</animal>
Run Code Online (Sandbox Code Playgroud)

我尝试过简单的解决方案:

[XmlElement("Animal")]
public List<animal> Animals { get; set; }
Run Code Online (Sandbox Code Playgroud)

但它会引发错误,因为它不期望对象类型为"cat".将[XmlInclude]标记添加到基类,派生类或整个包含类(让我们称之为动物园)对此没有帮助.

我可以将typeof指定用于单个类:

[XmlElement("Animal", typeof(cat))]
public List<animal> Animals { …
Run Code Online (Sandbox Code Playgroud)

.net c# polymorphism xmlserializer

7
推荐指数
1
解决办法
4693
查看次数

如何验证XmlSerializer的输出?

在C#/ .NET 2.0中,当我使用XmlSerializer 序列化对象时,根据XML模式验证输出的最简单方法是什么?

问题是用XmlSerializer编写无效的XML太容易了,我找不到一种方法来验证看起来不麻烦的XML.理想情况下,我希望在XmlSerializer中设置模式或者使用一个验证的XmlWriter.

c# validation schema serialization xmlserializer

6
推荐指数
1
解决办法
3480
查看次数

性能:XmlSerializer vs XmlReader vs XmlDocument vs XDocument

我正在开发一个小型Web项目,并希望读/写XML文件.表现是我​​的第一要务.

我来这篇关于比较上述方法的伟大帖子除外XmlSerializer.

我更喜欢,XmlSerializer因为它使代码更清洁.但我不知道它的表现.XmlSerializer内部使用什么样的写入XML文件?

.net xmldocument xmlreader linq-to-xml xmlserializer

6
推荐指数
1
解决办法
7109
查看次数

XmlSerializer和工厂创建的元素

我正在尝试序列化/反序列化具有工厂创建的成员的对象.例如,假设有一个类型的成员Foo,它使用FooFactory.CreateFoo(int bar)进行实例化.

我目前的想法是

1.创建自定义XmlReader(例如,从XmlTextReader派生),并将工厂附加到它

2.Implement IXmlSerializable

3.在ReadXml()中,我可以从读者手中抢到工厂.

不确定这是否是最优雅的方式,是否有人做过类似的尝试?

.net c# xml-serialization factory-pattern xmlserializer

6
推荐指数
1
解决办法
1057
查看次数

XMLSerialize一个ObservableCollection

我在observable集合的xml序列化中遇到问题.

这是我序列化的内容:

public enum Status { Pending, Active, Completed, Cancelled }

public abstract class Entity : INotifyPropertyChanged
{
    ...
}

public class UserStory : Entity
{
    public uint StoryID { get; set; }
    public Status Status { get; set; }
    ...
    public ObservableCollection<Task> Tasks { get; set; }
}

public class Task : Entity
{
    public uint TaskID { get; set; }
    ...
}
Run Code Online (Sandbox Code Playgroud)

这是我如何序列化它:

public static void SerializeObjectToXML<T>(T item, string FilePath)
{
    XmlSerializer xs = new XmlSerializer(typeof(T));
    using (StreamWriter …
Run Code Online (Sandbox Code Playgroud)

c# .net-4.0 observablecollection xmlserializer

6
推荐指数
1
解决办法
2万
查看次数

如何使类反序列化为不同的名称

例如:

<apple />
Run Code Online (Sandbox Code Playgroud)

将序列化为一个名为"苹果"的类.但是,如果我想将该类称为"Dragon",它将不会序列化(这是有道理的).我想知道如何标记"龙",这样当XmlSerializer看到它时,它知道"龙"是一样的

.net c# xml xmlserializer

6
推荐指数
2
解决办法
1531
查看次数

XmlSerializer是否支持属性名称更改(版本容错)

我有

public bool Included { get; set; }
Run Code Online (Sandbox Code Playgroud)

我想改为:

public bool IsIncluded { get; set; }
Run Code Online (Sandbox Code Playgroud)

我想要向后兼容.我想只在代码中定义IsIncluded,但是能够读取属性为"Included"的旧xml.

XmlSerializer是否支持它以及如何支持它?

注意:我尝试没有成功...(不反序列化)

    public bool IsIncluded { get; set; }

    [Obsolete]
    public bool Included
    {
        set { IsIncluded = value; }
        get { return IsIncluded; }
    }
Run Code Online (Sandbox Code Playgroud)

更新我只是想添加我更喜欢我的解决方案,因为我希望我的xml变成IsIncluded,对我而言,更合适.像我一样(下面的解决方案),将使我能够更改xml,但保持以前的版本正常工作.从长远来看,我可能会删除代码以支持旧版本.

更新2018-02-01请在下面的解决方案和建议的解决方案中查看Greg Petersen的评论.他提出了一个很好的解决方案,以便将校正封装在应该完成的地方(类).哇!!!

c# properties version xmlserializer

6
推荐指数
1
解决办法
2137
查看次数

使用多种类型反序列化 XML

我正在尝试反序列化 XML,其中一些相同的名称标签具有不同的 xsi 类型:

<user-defined-data-row>
  <field name="entity">
    <field-value xsi:type="field-text-valueType">
      <value>Test</value>
    </field-value>
  </field>
  <field name="expiry_date">
    <field-value xsi:type="field-date-valueType">
      <value>2001-10-07</value>
    </field-value>
  </field>
</user-defined-data-row>
Run Code Online (Sandbox Code Playgroud)

这很容易通过将 xml 反序列化到这个模型中来实现:

[XmlRoot(ElementName = "field-value", Namespace = "http://www.crsoftwareinc.com/xml/ns/titanium/common/v1_0")]
[XmlType("field-text-valueType")]
public class Fieldvalue
{
    [XmlElement(ElementName = "value", Namespace = "http://www.crsoftwareinc.com/xml/ns/titanium/common/v1_0")]
    public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

唯一不同的是 XML 中的类型:

字段文本值类型

字段日期值类型

我怎样才能让 C# 类使用类似的东西来解释这两种类型

[XmlType("field-text-valueType")]
Run Code Online (Sandbox Code Playgroud)

编辑:反序列化而不是序列化

c# xml xml-serialization xsi xmlserializer

6
推荐指数
1
解决办法
2892
查看次数