问题描述
我正在尝试反序列化NuGet NuSpec。我已经完成所有工作,并尝试添加对(元数据的)存储库元素的支持。由于某种原因,它不会填充Repository元素,我也无法弄清原因。我编写了一个独立的cs文件,该文件应演示该问题。谁能告诉我我做错了什么,它不会反序列化Repository元素?
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using FluentAssertions;
using Xunit;
namespace PipelineFunctions.Tests.Build.Nuget
{
public class SingleFilePackageTestForStackOverflow
{
[Fact]
public void Fromtest()
{
var xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<package xmlns=""http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd"">
<Metadata>
<id>YadaYada.Amazon.Data.Test</id>
<version>20.271.10</version>
<authors>Amazon.Data.Test</authors>
<owners>Amazon.Data.Test</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Package Description</description>
<repository type=""git"" url=""https://git-codecommit.us-east-1.amazonaws.com/v1/repos/zzzzz"" branch=""fast06"" commit=""51d5ea8ec9aefcd8a6d6c8a4c37a3fffe7c8d12f"" />
<dependencies>
<group targetFramework="".NETCoreApp3.1"">
<dependency id=""YadaYada.Amazon.Data"" version=""20.271.10"" exclude=""Build,Analyzers"" />
<dependency id=""YadaYada.Amazon.Entity.Test"" version=""20.271.10"" exclude=""Build,Analyzers"" />
<dependency id=""FluentAssertions"" version=""5.10.3"" exclude=""Build,Analyzers"" />
<dependency id=""Microsoft.NET.Test.Sdk"" version=""16.7.1"" exclude=""Build,Analyzers"" />
<dependency id=""YadaYada.Autoparts.Entity.Test"" version=""20.265.6"" exclude=""Build,Analyzers"" />
<dependency id=""YadaYada.Data.Library.Test"" version=""20.271.29"" exclude=""Build,Analyzers"" />
<dependency id=""coverlet.collector"" version=""1.3.0"" exclude=""Build,Analyzers"" />
<dependency id=""xunit"" version=""2.4.1"" exclude=""Build,Analyzers"" />
<dependency id=""xunit.runner.visualstudio"" version=""2.4.3"" exclude=""Build,Analyzers"" />
</group>
</dependencies>
</Metadata>
</package>";
var p = Package.From(xml);
// this passes
p.Metadata.Id.Should().Be("YadaYada.Amazon.Data.Test");
// this fails
p.Metadata.Repository.Url.Should().NotBeNullOrEmpty();
}
[XmlRoot(ElementName = "package")]
public class Package
{
[XmlElement(ElementName = "Metadata")]
public Metadata Metadata { get; set; } = new Metadata();
[XmlAttribute(AttributeName = "xmlns")]
public string Xmlns { get; set; }
public static Package From(string text)
{
var serializers = new[]
{
new XmlSerializer(typeof(Package),null,new XmlRootAttribute("package"),"http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd"),new XmlSerializer(typeof(Package),"http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd")};
using var reader = new XmlTextReader(new StringReader(text));
foreach (var xmlSerializer in serializers)
{
if (xmlSerializer.CanDeserialize(reader))
{
var deserialize = xmlSerializer.Deserialize( reader) as Package;
return deserialize;
}
}
throw new NotSupportedException($"Cannot deserialize {text}");
}
}
[XmlRoot(ElementName = "Metadata")]
public class Metadata
{
[XmlElement(ElementName = "id")]
public string Id { get; set; }
[XmlElement(ElementName = "version")]
public string Version { get; set; }
[XmlElement(ElementName = "authors")]
public string Authors { get; set; }
[XmlElement(ElementName = "owners")]
public string Owners { get; set; }
[XmlElement(ElementName = "requireLicenseAcceptance")]
public string RequireLicenseAcceptance { get; set; }
[XmlElement(ElementName = "description")]
public string Description { get; set; }
[XmlElement(ElementName = "dependencies")]
public Dependencies Dependencies { get; set; } = new Dependencies();
[XmlElement(ElementName = "repository")]
public Repository Repository { get; set; } = new Repository();
}
[XmlRoot(ElementName = "repository")]
public class Repository
{
[XmlElement(ElementName = "type")]
public string Type { get; set; }
[XmlElement(ElementName = "url")]
public string Url { get; set; }
[XmlElement(ElementName = "branch")]
public string Branch { get; set; }
[XmlElement(ElementName = "commit")]
public string Commit { get; set; }
}
[XmlRoot(ElementName = "dependencies")]
public class Dependencies
{
[XmlElement(ElementName = "group")]
public Group Group { get; set; } = new Group();
}
[XmlRoot(ElementName = "group")]
public class Group
{
[XmlElement(ElementName = "dependency")]
public List<Dependency> Dependency { get; set; } = new List<Dependency>();
[XmlAttribute(AttributeName = "targetFramework")]
public string TargetFramework { get; set; }
}
[XmlRoot(ElementName = "dependency")]
public class Dependency
{
[XmlAttribute(AttributeName = "id")]
public string Id { get; set; }
[XmlAttribute(AttributeName = "version")]
public string Version { get; set; }
[XmlAttribute(AttributeName = "exclude")]
public string Exclude { get; set; }
}
}
}
解决方法
repository元素由属性定义,因此应改为使用XmlAttribute。但是,我高度建议您研究从nuspec XSD自动生成类(搜索如何“从XSD生成C#类”)。当您具有定义良好的XML结构时,应避免创建自己的类