繁体   English   中英

C# XML 反序列化,其中节点属性不区分大小写,即使 xml 区分大小写

[英]C# XML Deserialization where node attribute is case-insensitive even though xml is case sensitive

我正在尝试从 XML 文档中读取 PackageReferences。

我的 xml 文件如下所示:

<Project>
  <ItemGroup>
    <PackageReference Update="PackageName" Version="PackageVersion" />
  </ItemGroup>
</Project>

<Project>
  <ItemGroup>
    <PackageReference Update="PackageName" version="PackageVersion" />
  </ItemGroup>
</Project>

(第一个例子在“Version”中有一个大写的 V,第二个例子在“version”中有一个小写的 v)

我知道 XML 区分大小写。 不幸的是,提交xml文件进行处理的客户经常犯这个大小写错误。 由于客户的数量和对这些类似文件的手动编辑,很难保持一致。 我有哪些选择可以让我的 C# 程序安全地忽略大小写? 目前,我的程序仅捕获“版本”中大写 V 的值,并为小写“版本”示例输入null 在这两种情况下,我仍然需要PackageVersion值。

这是我的代码:

Reader.cs

var xmlResolver = new XmlSecureResolver(new XmlUrlResolver(), new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None));
using (var sr = new StringReader(this.FileSystem.File.ReadAllText(path)))
{
  var textReader = new XmlTextReader(sr) { Namespaces = false, XmlResolver = null };
  var serializer = new XmlSerializer(typeof(Project));
  return (Project)serializer.Deserialize(textReader);
}

Project.cs部分 class:

{
    using System;
    using System.Xml.Serialization;

    [Serializable]
    public partial class Project
    {
        private ProjectItemGroup[] itemGroupField;

        [XmlElement("ItemGroup")]
        public ProjectItemGroup[] ItemGroup
        {
            //...
        }
    }

    [Serializable]
    public partial class ProjectItemGroup
    {
        private Package[] packageReferenceField;

        [XmlElement("PackageReference")]
        public Package[] PackageReference
        {
            get
            {
                return this.packageReferenceField;
            }
            set
            {
                this.packageReferenceField = value;
            }
        }
    }

}

Package.cs

    [Serializable]
    public class Package
    {
        [XmlAttribute(AttributeName = "Update")]
        public string Id { get; set; }

        [XmlAttribute(AttributeName = "Version")]
        public string Version { get; set; }
    }

我在这里查看了所有properties文档: https://learn.microsoft.com/en-us/do.net/api/system.xml.xmltextreader.namespaces?view.net-6.0并且看不到一种方法忽略大小写。 (早些时候,我能够忽略根节点上的命名空间属性,如下所述: C# XML Deserialization where root node sometimes has namespace attribute

我可能看到的选项是将整个文档小写并重新编写程序以期望所有小写值。 另一种选择可能是还为 version 添加一个小写字段,并以某种方式组合大写Version和小写version的结果。 我缺少一些不那么骇人听闻的东西吗?

感谢 @canton7 提出了将XmlTextReader子类化以覆盖LocalName的想法。 我最终对Reader.cs进行了以下更改:

public class CaseInsensitiveXmlTextReader : XmlTextReader
{
  public CaseInsensitiveXmlTextReader(System.IO.TextReader reader) : base(reader) { }
  public override string LocalName
  {
    get
    {
      if (String.Equals(base.LocalName, "version", StringComparison.Ordinal))
      {
        return "Version";
      }
      else
      {
        return base.LocalName;
      }
    }
  }
}

然后我更新了 textReader 以使用 CaseInsensitiveXmlTextReader:

var textReader = new CaseInsensitiveXmlTextReader(sr) { Namespaces = false, XmlResolver = xmlResolver };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM