xsi:type 属性搞乱了 C# XML 反序列化

2024-05-15

我使用 XSD.exe 根据 XML 架构(.xsd 文件)自动生成 C# 对象。我正在反序列化 OpenCover 输出,但其中一个部分类未正确生成。

这是导致异常的行:

<MethodPoint xsi:type="SequencePoint" vc="0" uspid="1" ordinal="0" offset="0" sl="19" sc="9" el="19" ec="10" bec="0" bev="0" fileid="1" />

这是 MethodPoint 类的简化版本:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class CoverageSessionModulesModuleClassesClassMethodsMethodMethodPoint {
    private string vcField;
    private string uspidField;
    private string ordinalField;
    private string offsetField;
    private string slField;
    private string scField;
    private string elField;
    private string ecField;
    private string becField;
    private string bevField;
    private string fileidField;
}

现在我已经浏览了很多 .xml 文件,但 OpenCover 输出文件是唯一在属性中包含冒号的文件。 MethodPoint 对象也是唯一在属性中包含冒号的对象。如您所见,该类不包含xsi:type属性,而且我知道由于冒号的原因,简单地添加它是行不通的。你如何处理xsi prefix?

以下是从 OpenCover XML 文件之一生成的原始 .xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="CoverageSession" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="Summary">
    <xs:complexType>
      <xs:attribute name="numSequencePoints" type="xs:string" />
      <xs:attribute name="visitedSequencePoints" type="xs:string" />
      <xs:attribute name="numBranchPoints" type="xs:string" />
      <xs:attribute name="visitedBranchPoints" type="xs:string" />
      <xs:attribute name="sequenceCoverage" type="xs:string" />
      <xs:attribute name="branchCoverage" type="xs:string" />
      <xs:attribute name="maxCyclomaticComplexity" type="xs:string" />
      <xs:attribute name="minCyclomaticComplexity" type="xs:string" />
      <xs:attribute name="visitedClasses" type="xs:string" />
      <xs:attribute name="numClasses" type="xs:string" />
      <xs:attribute name="visitedMethods" type="xs:string" />
      <xs:attribute name="numMethods" type="xs:string" />
    </xs:complexType>
  </xs:element>
  <xs:element name="CoverageSession" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded">
        <xs:element ref="Summary" />
        <xs:element name="Modules">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Module" minOccurs="0" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="FullName" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
                    <xs:element name="ModuleName" type="xs:string" minOccurs="0" msdata:Ordinal="2" />
                    <xs:element ref="Summary" minOccurs="0" maxOccurs="unbounded" />
                    <xs:element name="Files" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="File" minOccurs="0" maxOccurs="unbounded">
                            <xs:complexType>
                              <xs:attribute name="uid" type="xs:string" />
                              <xs:attribute name="fullPath" type="xs:string" />
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                    <xs:element name="Classes" minOccurs="0" maxOccurs="unbounded">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="Class" minOccurs="0" maxOccurs="unbounded">
                            <xs:complexType>
                              <xs:sequence>
                                <xs:element name="FullName" type="xs:string" minOccurs="0" />
                                <xs:element ref="Summary" minOccurs="0" maxOccurs="unbounded" />
                                <xs:element name="Methods" minOccurs="0" maxOccurs="unbounded">
                                  <xs:complexType>
                                    <xs:sequence>
                                      <xs:element name="Method" minOccurs="0" maxOccurs="unbounded">
                                        <xs:complexType>
                                          <xs:sequence>
                                            <xs:element name="MetadataToken" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
                                            <xs:element name="Name" type="xs:string" minOccurs="0" msdata:Ordinal="2" />
                                            <xs:element ref="Summary" minOccurs="0" maxOccurs="unbounded" />
                                            <xs:element name="FileRef" minOccurs="0" maxOccurs="unbounded">
                                              <xs:complexType>
                                                <xs:attribute name="uid" type="xs:string" />
                                              </xs:complexType>
                                            </xs:element>
                                            <xs:element name="SequencePoints" minOccurs="0" maxOccurs="unbounded">
                                              <xs:complexType>
                                                <xs:sequence>
                                                  <xs:element name="SequencePoint" minOccurs="0" maxOccurs="unbounded">
                                                    <xs:complexType>
                                                      <xs:attribute name="vc" type="xs:string" />
                                                      <xs:attribute name="uspid" type="xs:string" />
                                                      <xs:attribute name="ordinal" type="xs:string" />
                                                      <xs:attribute name="offset" type="xs:string" />
                                                      <xs:attribute name="sl" type="xs:string" />
                                                      <xs:attribute name="sc" type="xs:string" />
                                                      <xs:attribute name="el" type="xs:string" />
                                                      <xs:attribute name="ec" type="xs:string" />
                                                      <xs:attribute name="bec" type="xs:string" />
                                                      <xs:attribute name="bev" type="xs:string" />
                                                      <xs:attribute name="fileid" type="xs:string" />
                                                    </xs:complexType>
                                                  </xs:element>
                                                </xs:sequence>
                                              </xs:complexType>
                                            </xs:element>
                                            <xs:element name="BranchPoints" minOccurs="0" maxOccurs="unbounded">
                                              <xs:complexType>
                                                <xs:sequence>
                                                  <xs:element name="BranchPoint" minOccurs="0" maxOccurs="unbounded">
                                                    <xs:complexType>
                                                      <xs:attribute name="vc" type="xs:string" />
                                                      <xs:attribute name="uspid" type="xs:string" />
                                                      <xs:attribute name="ordinal" type="xs:string" />
                                                      <xs:attribute name="offset" type="xs:string" />
                                                      <xs:attribute name="sl" type="xs:string" />
                                                      <xs:attribute name="path" type="xs:string" />
                                                      <xs:attribute name="offsetend" type="xs:string" />
                                                      <xs:attribute name="fileid" type="xs:string" />
                                                      <xs:attribute name="offsetchain" type="xs:string" />
                                                    </xs:complexType>
                                                  </xs:element>
                                                </xs:sequence>
                                              </xs:complexType>
                                            </xs:element>
                                            <xs:element name="MethodPoint" minOccurs="0" maxOccurs="unbounded">
                                              <xs:complexType>
                                                <xs:attribute name="vc" type="xs:string" />
                                                <xs:attribute name="uspid" type="xs:string" />
                                                <xs:attribute name="ordinal" type="xs:string" />
                                                <xs:attribute name="offset" type="xs:string" />
                                                <xs:attribute name="sl" type="xs:string" />
                                                <xs:attribute name="sc" type="xs:string" />
                                                <xs:attribute name="el" type="xs:string" />
                                                <xs:attribute name="ec" type="xs:string" />
                                                <xs:attribute name="bec" type="xs:string" />
                                                <xs:attribute name="bev" type="xs:string" />
                                                <xs:attribute name="fileid" type="xs:string" />
                                              </xs:complexType>
                                            </xs:element>
                                          </xs:sequence>
                                          <xs:attribute name="visited" type="xs:string" />
                                          <xs:attribute name="cyclomaticComplexity" type="xs:string" />
                                          <xs:attribute name="sequenceCoverage" type="xs:string" />
                                          <xs:attribute name="branchCoverage" type="xs:string" />
                                          <xs:attribute name="isConstructor" type="xs:string" />
                                          <xs:attribute name="isStatic" type="xs:string" />
                                          <xs:attribute name="isGetter" type="xs:string" />
                                          <xs:attribute name="isSetter" type="xs:string" />
                                          <xs:attribute name="skippedDueTo" type="xs:string" />
                                        </xs:complexType>
                                      </xs:element>
                                    </xs:sequence>
                                  </xs:complexType>
                                </xs:element>
                              </xs:sequence>
                            </xs:complexType>
                          </xs:element>
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                  <xs:attribute name="skippedDueTo" type="xs:string" />
                  <xs:attribute name="hash" type="xs:string" />
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:choice>
    </xs:complexType>
  </xs:element>
</xs:schema>

简短的回答是你需要手动添加[XmlInclude(typeof(SequencePoint))] https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlincludeattribute.aspx给你的MethodPoint class:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[XmlInclude(typeof(SequencePoint))]
public partial class CoverageSessionModulesModuleClassesClassMethodsMethodMethodPoint {
    private string vcField;
    private string uspidField;
    private string ordinalField;
    private string offsetField;
    private string slField;
    private string scField;
    private string elField;
    private string ecField;
    private string becField;
    private string bevField;
    private string fileidField;
}

你还需要做SequencePoint继承自MethodPoint如果它还没有这样做的话。

你需要这样做是因为,当您使用 xsd.exe 从 XML 示例生成 XSD 时,然后依次是 c# 类,它显然不会在属性添加时自动将多态子类型属性添加到基类型中xsi:type="SomePolymoirphicSubType"出现在 XML 中,尽管它看起来应该出现。

说明如下。这xsi:type属性,简称{http://www.w3.org/2001/XMLSchema-instance}type, is a w3c 标准属性 https://www.w3.org/TR/xmlschema-1/#xsi_type允许元素显式断言其类型,例如当它是预期元素类型的多态子类型时。XmlSerializer 支持该属性 https://msdn.microsoft.com/en-us/library/ca1ks327.aspx并将使用它来确定要为此类多态类型反序列化的对象的实际类型。但需要告知提前所有可能的类型使用XmlIncludeAttribute https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlincludeattribute.aspx。因此,如果我创建以下类型层次结构:

[XmlInclude(typeof(SequencePoint))]
public class MethodPoint
{
}

public class SequencePoint : MethodPoint
{
}

并将其序列化如下:

var test = new SequencePoint();

var serializer = new XmlSerializer(typeof(MethodPoint));
var sb = new StringBuilder();
using (var stream = new StringWriter(sb))
    serializer.Serialize(stream, test);

Console.WriteLine(sb);

我得到以下 XML:

<MethodPoint 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
 xsi:type="SequencePoint" />

然后如果我使用反序列化它var serializer = new XmlSerializer(typeof(MethodPoint)),我得到一个SequencePoint,不是它的基类。如果我使用 xsd.exe 为这些类生成架构,我会得到:

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="MethodPoint" nillable="true" type="MethodPoint" />
  <xs:complexType name="MethodPoint" />
  <xs:complexType name="SequencePoint">
    <xs:complexContent mixed="false">
      <xs:extension base="MethodPoint" />
    </xs:complexContent>
  </xs:complexType>
  <xs:element name="SequencePoint" nillable="true" type="SequencePoint" />
</xs:schema>

注意xs:extension?这就是 XSD 指示多态子类型的方式。然后,如果我向后运行 xsd.exe 来重新生成我的类,我会得到:

[System.Xml.Serialization.XmlIncludeAttribute(typeof(SequencePoint))]
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
public partial class MethodPoint {
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)]
public partial class SequencePoint : MethodPoint {
}

如您所见,XmlIncludeAttribute存在并且生成的类与原始类等效。到目前为止一切都很顺利。

但是,当从示例 XML 文件推断 XSD 时,xsd.exe 似乎没有识别出xsi:type属性。例如,如果我从上面的简单 XML 创建 XSD,结果是:

<xs:schema id="MethodPoint" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
  <xs:element name="MethodPoint" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
    <xs:complexType>
      <xs:choice minOccurs="0" maxOccurs="unbounded" />
    </xs:complexType>
  </xs:element>
</xs:schema>

多态亚型完全缺失。从此 XSD 生成的类将无法反序列化该 XML。

因此,使用 xsd.exe 从 XML 示例生成 C# 类似乎不如从正确的 XSD 生成它们那么可靠。具体来说,在以下情况下xsi:type如果出现在 XML 文件中,您将需要手动修复生成的类或生成的 XSD 以实现所需的层次结构。这可能是该工具的限制或错误。

(限制/错误也会出现在将 XML 粘贴为类 https://learn.microsoft.com/en-us/dotnet/framework/wcf/generating-data-type-classes-from-xml它使用xsd.exe内部。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

xsi:type 属性搞乱了 C# XML 反序列化 的相关文章

随机推荐

  • 在 ec2 上托管 Rails

    我想将 Rails 部署到亚马逊 ec2 上 我看过 poolparty 和 ec2onrails 但似乎都不再维护了 人们用什么来做到这一点 都是自制的木偶和卡皮斯特拉诺 还是有一个项目可以让我继续下去 我可以推荐两个项目 如果您有一个
  • 合并 csv 文件 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何在 PHP 或 joomla 中将多个 CSV 文件合并为一个 csv 文件 将文件夹中 csv 文件中的所有数据合并到文本文件中 通
  • 生产者/消费者的不同语言

    我想知道是否可以通过 AMQP 和 RabbitMQ 对生产者和消费者使用不同的语言 例如 Java 代表生产者 python php 代表消费者 或者反之亦然 是的 AMQP 与语言无关 这意味着只要您有可以连接到 AMQP 的客户端sa
  • 使用Jquery(或js)在html表格上循环遍历列的单元格(不是行的单元格)?

    使用 jQuery 循环遍历单元格或行很简单 但循环遍历列的单元格并不简单 for cells of rows I will do this table tr each function index elem loop through ce
  • 将所有分号替换为空格 pt2

    我尝试对 2000 多行关键字的列表运行文本分析 但它们的列出方式如下 战略 管理风格 组织 所以当我使用 tm 删除标点符号时 它就变成了 组织的战略管理风格 我认为这在某种程度上破坏了我常用术语的分析 我尝试过使用 vector lt
  • Spark/Gradle -- 在 build.gradle 中获取 IP 地址以用于启动 master 和worker

    我在基本层面上了解 build gradle 构建脚本的各个移动部分 但无法将它们全部结合在一起 在 Apache Spark 独立模式下 只需尝试从 build gradle 在同一个机器上启动 master 和worker 稍后将使用
  • Spring RESTful控制器方法改进建议

    我是 Spring REST 和 Hibernate 的新手 也就是说 我尝试组合一个企业级控制器方法 我计划将其用作未来开发的模式 您认为可以通过哪些方法来改进 我确信有很多 RequestMapping value user metho
  • 从脚本内更改自动热键托盘图标

    如何从 Autohotkey 脚本中将托盘图标更改为 my ico 例如 当脚本暂停时 为此 我在托盘菜单中提出了自己的 暂停脚本 菜单项 SingleInstance ignore Menu Tray Tip AutoCase 0 11
  • IE9-11 检测变换样式:preserve-3d

    我为一个项目制作了一个 3d 类型的菜单 自然 IE 会引起问题 因为 IE10 即使 3d 变换工作 也不支持变换样式 preserve 3d 我尝试了解决方法 通过对 3d 菜单容器的每个子元素应用变换 但至少可以说 动画看起来很糟糕
  • 文本溢出:省略号显示不同的字符

    我这里遇到了一些 CSS 问题 看这张图片 https www flickr com photos 125543025 N07 saved 1 在此图像中 我为文本 INTENSE TRAINING 添加了 CSS 样式 sample st
  • 我们什么时候应该在 Django 中使用“db_index=True”?

    当我们应该定义db index True在模型字段上 我正在尝试优化应用程序并且我想了解更多信息db index 什么情况下我们应该使用它 文档说使用db index True在模型字段上用于加速查找 但在存储和内存方面略有缺点 我们应该使
  • 如何制作过期/签名视频嵌入网址

    我是新来的 正在学习网络开发等等 我只知道如何将我的视频嵌入网站中 任何菜鸟都可以轻松获得源代码 他们也可以嵌入它 但在许多网站中 视频 src 均使用重定向器链接进行编码 例如 它会在一段时间后过期 在本例中是一天 我了解到这是一个签名网
  • 使用 QtWebEngine 将 C++ 对象暴露给 Qt 中的 Javascript

    使用 QtWebkit 可以通过以下方式将 C 对象公开给 JavascriptQWebFrame addToJavaScriptWindowObject如中所述https stackoverflow com a 20685002 5959
  • Android Espresso 单击按钮时出现错误

    我正在尝试使用 espresso 框架为 Android 应用程序编写一些 UI 测试 现在我只是检查启动屏幕上是否存在所有元素 然后尝试单击登录按钮 单击按钮时 测试由于错误而失败 我似乎无法理解为什么会发生这种情况 我的测试代码是 Ru
  • Qt 布局,在小部件大小更改后调整到最小大小

    基本上我有一个QGridLayout里面有一些小部件 最重要的是 2 个标签 我用它们将图像绘制到屏幕上 好吧 如果用户愿意 他可以更改传入图像的分辨率 从而强制标签调整大小 我们假设标签的初始大小是320x240 用户将 VideoMod
  • Python 中的字符串slugification

    我正在寻找 slugify 字符串的最佳方法 蛞蝓 是什么 https stackoverflow com questions 427102 in django what is a slug 我当前的解决方案基于这个食谱 http code
  • bash:gitolite:找不到命令

    我正在尝试使用 Gitolite 在 Gitlab 中创建一个新分支 我完成安装步骤 当我遇到 设置 gitolite 部分时 我遇到了麻烦 我跟着这个link http sitaramc github com gitolite setup
  • 如何在 kubernetes 中将秘密标记为可选?

    来自文档 除非将秘密标记为可选 否则必须先创建秘密 然后再将其作为环境变量在 pod 中使用 引用不存在的 Secret 将阻止 pod 启动 如何将秘密标记为可选 您正在寻找的是 name ENV NAME valueFrom secre
  • ASP.NET Core MVC 视图组件搜索路径

    在此处的文档中 https learn microsoft com en us aspnet core mvc views view components view aspnetcore 2 2 https learn microsoft
  • xsi:type 属性搞乱了 C# XML 反序列化

    我使用 XSD exe 根据 XML 架构 xsd 文件 自动生成 C 对象 我正在反序列化 OpenCover 输出 但其中一个部分类未正确生成 这是导致异常的行