更改 XML 序列化中元素的类型

2023-12-09

我在 XML 序列化方面遇到了巨大的问题。我有两个类,都需要可序列化。在继承的类中,我想更改序列化行为,以便将字符串属性序列化为复杂类型。

public class Animal
{
    [XmlElement(ElementName = "NAME")]
    public string Name { get; set; }
    public virtual bool ShouldSerializeName() { return true; }
}

public class Cat : Animal
{
    public override bool ShouldSerializeName() { return false; }

    [XmlElement(ElementName = "NAME")]
    public NameAndType Name2 { get; set; }
}

public class NameAndType
{
    public string Name { get; set; }
    public string Type { get; set; }
}

...

var cat = new Cat {Name2 = new NameAndType {Name = "LittleCat"}};
new XmlSerializer(typeof(Cat)).Serialize(Console.Out, cat);

我尝试过不同的方法,但没有找到一种方法来改变NAME元素得到序列化。 通过上面的示例,我收到错误消息:

The XML element 'NAME' from namespace '' is already present in the current scope. Use XML attributes to specify another XML name or namespace for the element.


您收到错误的原因是,在XmlSerializer 代码生成,代码生成器不理解这两个潜在的NAME上的元素Cat永远不会同时序列化,因此会抛出异常。

相反,您可以申请XmlAnyElementAttribute虚拟财产返回XElement,然后手动创建并返回适当的XElement对于层次结构中每个类的名称:

[XmlInclude(typeof(Cat))]
public class Animal
{
    [XmlIgnore]
    public string Name { get; set; }

    [XmlAnyElement]
    public virtual XElement XmlName
    {
        get
        {
            return Name == null ? null : new XElement("NAME", Name);
        }
        set
        {
            Name = (value == null ? null : value.Value);
        }
    }
}

public class Cat : Animal
{
    // Must be cached as per https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer%28v=vs.110%29.aspx
    static XmlSerializer nameSerializer;

    static Cat()
    {
        nameSerializer = new XmlSerializer(typeof(NameAndType), new XmlRootAttribute("NAME"));
    }

    [XmlIgnore]
    public NameAndType Name2 { get; set; }

    [XmlAnyElement]
    public override XElement XmlName
    {
        get
        {
            return (Name2 == null ? null : XObjectExtensions.SerializeToXElement(Name2, nameSerializer, true));
        }
        set
        {
            Name2 = (value == null ? null : XObjectExtensions.Deserialize<NameAndType>(value, nameSerializer));
        }
    }
}

使用扩展方法:

public static class XObjectExtensions
{
    public static T Deserialize<T>(this XContainer element)
    {
        return element.Deserialize<T>(new XmlSerializer(typeof(T)));
    }

    public static T Deserialize<T>(this XContainer element, XmlSerializer serializer)
    {
        using (var reader = element.CreateReader())
        {
            object result = serializer.Deserialize(reader);
            if (result is T)
                return (T)result;
        }
        return default(T);
    }

    public static XElement SerializeToXElement<T>(this T obj)
    {
        return obj.SerializeToXElement(new XmlSerializer(obj.GetType()), true);
    }

    public static XElement SerializeToXElement<T>(this T obj, XmlSerializer serializer, bool omitStandardNamespaces)
    {
        var doc = new XDocument();
        using (var writer = doc.CreateWriter())
        {
            XmlSerializerNamespaces ns = null;
            if (omitStandardNamespaces)
                (ns = new XmlSerializerNamespaces()).Add("", ""); // Disable the xmlns:xsi and xmlns:xsd lines.
            serializer.Serialize(writer, obj, ns);
        }
        var element = doc.Root;
        if (element != null)
            element.Remove();
        return element;
    }
}

其中,对于一个List<Animal>,生成这样的 XML:

<ArrayOfAnimal xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Animal>
        <NAME>duck</NAME>
    </Animal>
    <Animal xsi:type="Cat">
        <NAME>
            <Name>Smokey</Name>
            <Type>Siamese</Type>
        </NAME>
    </Animal>
</ArrayOfAnimal>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更改 XML 序列化中元素的类型 的相关文章

随机推荐

  • 从 JSP 返回 JSONP 而不是 JSON

    I found 这个问题从jsp将响应类型设置为json 但我需要将响应类型设置为jsonp以进行跨域访问 还会是这样吗 response setContentType application javascript 并将来自jsp的响应包装
  • 如何使用 R8 在堆栈跟踪中保留原始行号?

    我正在尝试找出如何使用 R8 保留原始行号 使用当前的AndroidStudio制作应用程序并使用R8对其进行混淆 甚至上传mapping txt将文件上传到 Google Play Console 后 用户的堆栈跟踪在某些情况下是无用的
  • T-SQL 中的编辑距离

    我对 T SQL 计算 Levenshtein 距离的算法感兴趣 我在 TSQL 中实现了标准 Levenshtein 编辑距离函数 并进行了多项优化 与我所知的其他版本相比 速度有所提高 如果两个字符串的开头有共同的字符 共享前缀 结尾有
  • 无法使最大宽度与 Bootstrap 下拉菜单一起使用

    我有一个 Bootstrap 下拉菜单 在某些情况下 菜单项可能非常大 所以我需要设置一个max width 另外 我不希望菜单项被剪切 所以我必须使用white space normal也 问题是我的max width被完全忽略 如果我设
  • File.Copy 与手动 FileStream.Write 复制文件

    我的问题是关于文件复制性能 我们有一个媒体管理系统 需要将文件系统上的大量文件移动到不同位置 包括同一网络上的 Windows 共享 FTP 站点 AmazonS3 等 当我们都在一个 Windows 网络上时 我们可以使用System I
  • Delphi 编译器指令反向求值参数

    这个使用 Math pas 中的 IFThen 函数的 delphi 两行代码给我留下了深刻的印象 但是 它首先评估 DB ReturnFieldI 这很不幸 因为我需要调用 DB first 来获取第一条记录 DB RunQuery se
  • 如何对只读实例属性进行输入验证?

    发布了一个非常相似的问题here 但没有公认的答案 没有代码示例 而且我不太喜欢按照那里提供的唯一一个答案所建议的使用外部库的想法 以下代码允许定义只读实例属性 class Point def init self x y self x x
  • 有充分的理由编写我自己的 daemonize 函数而不是使用 daemon(3) 吗?

    网上有很多守护进程的示例实现 我看到的大多数不使用 daemon 3 函数在后台运行程序 这只是一个品味 无知的问题 还是有充分的理由编写我自己的守护函数 使用 daemon 3 有什么具体的缺点吗 是不是没有安全感 daemon 函数历史
  • 核心数据中的可转换属性无法导出/与 iCloud 同步

    我在用NSPersistentCloudKitContainer 所有数据均在 iCloud 中同步 卸载应用程序后 它会正确同步 但是 需要对敏感数据进行加密 我将密码属性设置为可转换 因此在本地工作得很好 但是当我删除该应用程序时 再次
  • 在 Origin 中将破幂律实现为拟合函数

    再会 我正在尝试使用 origin OriginLab 中的函数生成器来创建一个新函数来适应破碎的幂律 http en wikipedia org wiki Power law Broken power law 所以 我想我已经把实际的功能
  • 从 GUI 类 PyQt4 以外的类更改进度条的值

    我有一个由 Qt 设计器创建的 GUI 类 其中有一个进度条 还有另一个类 其中完成所有数字运算 在此期间我希望进度条定期更新 我认为我会这样做的方式是在其他班级中做类似的事情 gui progressbar setValue some 但
  • 在没有 xts 对象的情况下在 PortfolioAnalytics 中创建有效前沿

    有没有办法在 PortfolioAnalytics 包中创建有效前沿而不指定资产回报的 xts 对象 相反 我想提供预期回报向量和协方差矩阵 有两种方法 首先 您可以提供一个包含矩阵的列表 其结构如下所示 然后调用 Optimize por
  • 在 Mac 应用程序中的保存对话框中包含 iCloud

    我已经实施了iCloud支持我的 Mac 基于文档的应用程序 NSDocument子类可以处理本地存储上打开的保存文件 并且iCloud 但是 我可以将我的文件上传到iCloud只需将其拖动到 打开新文件 面板上即可 当应用程序提示用户保存
  • 如何区分 EOF 字符和实际的文件结尾?

    When reading a file I understand the last character provided is an EOF Now what happens when I have an EOF character in
  • Mojarra 2.0.3 中复合组件所需属性抛出异常

    我一直在使用 JSF 2 0 复合组件 但我对其中的 require 属性有点困惑composite attribute标签的意思是做 文档指出 如果页面作者必须提供此属性的值 则必需的属性为 true 我将其解释为必须为所有具有复合属性的
  • apollo-android可以用作java客户端吗?

    我正在开发一个需要与 Github GraphQl API 通信的 Spring Boot 应用程序 apollo android 可以用于此目的吗 由于所有可用的稀缺文档以及示例项目都是用 android 编写的 所以我不确定 维护者在这
  • 获取距离直线最近的点

    我想要一个直接的 C 函数来获取距离线段 AB 最近的点 从点 P 抽象函数可能如下所示 我已经搜索过了 但没有找到可用的 由我 解决方案 public Point getClosestPointFromLine Point A Point
  • Pandas:根据子字符串删除重复项[重复]

    这个问题在这里已经有答案了 我有以下两列 来自 Pandas DataFrame antecedents consequents apple orange orange apple apple water apple pineapple w
  • 检查 PDO 是否存在的最佳方法是什么[重复]

    这个问题在这里已经有答案了 有人告诉我 rowCount 不安全 所以我想在这里问它 我有 2 个例子 想知道检查某些东西是否存在的最安全和最好的方法是什么 sql SELECT count FROM users WHERE usernam
  • 更改 XML 序列化中元素的类型

    我在 XML 序列化方面遇到了巨大的问题 我有两个类 都需要可序列化 在继承的类中 我想更改序列化行为 以便将字符串属性序列化为复杂类型 public class Animal XmlElement ElementName NAME pub