Visual Studio 16.8.4粘贴XML为类时忽略i:type类型名问题
问题产生的核心原因
VS 16.8.4内置的「粘贴XML为类」功能,底层复用了.NET SDK里xsd.exe的结构推断逻辑。这套逻辑默认将http://www.w3.org/2001/XMLSchema-instance命名空间下的i:type(也就是xsi:type)识别为XML序列化框架内置的类型占位标记,不会主动把属性值标注的类型名作为独立类生成的依据,最终就会出现元素被自动命名为父类名+元素名的嵌套类、子节点成员被推断为object类型的结果。
疑问一:是否存在不会忽略i:type属性的转换工具
- 有不少第三方的XML转C#类工具,核心逻辑就是主动解析xsi:type/i:type的标注值,不会像VS内置工具那样忽略这类元数据。遇到带i:type标注的元素时,工具会直接把标注的类型名作为生成类的类名,元素下的子节点作为类的公开成员。
- 这类工具生成的代码会自动为对应多态属性补上
[XmlInclude(typeof(具体类型))]序列化特性,不需要后续手动修改适配XML序列化逻辑,生成结果和预期的类结构完全匹配。
疑问二:让VS内置功能正确识别类型标注的简便修改方法
如果不想切换工具,只需要对XML做两点低成本修改,就能让VS的内置转换逻辑输出符合要求的代码:
- 把原本嵌套在父节点下、带i:type标注的元素,按照标注的类型名单独拆分为独立的顶层XML片段,让解析器能识别到独立的类结构,而不是将其作为父类的嵌套内部类。
- 给原位置的带i:type的元素保留属性标注,去掉原本嵌套在内部的子节点内容,避免解析器把嵌套内容算到父类的嵌套类结构里。
修改后的参考XML结构示例:
<?xml version="1.0" encoding="utf-16"?> <Screen xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <Object i:type="AlarmControlType" /> </Screen> <!-- 单独列出所有i:type标注的类型节点,供解析器识别类定义 --> <AlarmControlType> <blahblah></blahblah> </AlarmControlType>
批量处理技巧:如果大体积XML里有几十上百个i:type标注的类型,可以用任意文本编辑器的正则替换功能,批量提取所有i:type对应的类型名和内部子节点,自动生成独立的顶层类型片段,不需要逐行手动调整。
用修改后的XML执行「粘贴XML为类」操作,VS生成的代码会自动将Screen类下的Object属性类型识别为AlarmControlType,并独立生成对应名称的类,不会再自动生成ScreenObject这类嵌套类名。
内容的提问来源于stack exchange,提问作者TheColonel26
相关产品推荐
相关产品推荐

