【问题标题】:Deserialize Xml to different type将 Xml 反序列化为不同的类型
【发布时间】:2023-04-08 20:40:01
【问题描述】:

这个问题可能是我没有正确地问这个问题,但是冲突的名称和类使它变得困难。我想建立一个小工具,在我重构一些代码时跟踪我的代码指标。结果现在输出到我试图反序列化的文件。这是指标的摘要。 (对不起,我能做到的那么小)

<CodeMetricsReport Version="11">
<Targets>
    <Target Name="C:\Git\coab\GoldBox.Logging\bin\Debug\GoldBox.Logging.dll">
    <Modules>
        <Module Name="GoldBox.Logging.dll" AssemblyVersion="1.0.5978.28510">
        <Metrics>
            <Metric Name="MaintainabilityIndex" Value="88" />
            <Metric Name="CyclomaticComplexity" Value="30" />
            <Metric Name="ClassCoupling" Value="13" />
            <Metric Name="DepthOfInheritance" Value="1" />
            <Metric Name="LinesOfCode" Value="51" />
        </Metrics>
        <Namespaces>
            <Namespace Name="GoldBox.Logging">
            <Metrics>
                <Metric Name="MaintainabilityIndex" Value="88" />
                <Metric Name="CyclomaticComplexity" Value="30" />
                <Metric Name="ClassCoupling" Value="13" />
                <Metric Name="DepthOfInheritance" Value="1" />
                <Metric Name="LinesOfCode" Value="51" />
            </Metrics>
            <Types>
                <Type Name="Config">
                <Metrics>
                    <Metric Name="MaintainabilityIndex" Value="89" />
                    <Metric Name="CyclomaticComplexity" Value="9" />
                    <Metric Name="ClassCoupling" Value="5" />
                    <Metric Name="DepthOfInheritance" Value="1" />
                    <Metric Name="LinesOfCode" Value="15" />
                </Metrics>
                <Members>
                    <Member Name="BasePath.get() : string" File="C:\Git\coab\GoldBox.Logging\Config.cs" Line="8">
                    <Metrics>
                        <Metric Name="MaintainabilityIndex" Value="98" />
                        <Metric Name="CyclomaticComplexity" Value="1" />
                        <Metric Name="ClassCoupling" Value="0" />
                        <Metric Name="LinesOfCode" Value="1" />
                    </Metrics>
                    </Member>
                    <Member Name="BasePath.set(string) : void" File="C:\Git\coab\GoldBox.Logging\Config.cs" Line="8">
                    <Metrics>
                        <Metric Name="MaintainabilityIndex" Value="95" />
                        <Metric Name="CyclomaticComplexity" Value="1" />
                        <Metric Name="ClassCoupling" Value="0" />
                        <Metric Name="LinesOfCode" Value="1" />
                    </Metrics>
                    </Member>
                    <Member Name="LogPath.get() : string" File="C:\Git\coab\GoldBox.Logging\Config.cs" Line="9">
                    <Metrics>
                        <Metric Name="MaintainabilityIndex" Value="98" />
                        <Metric Name="CyclomaticComplexity" Value="1" />
                        <Metric Name="ClassCoupling" Value="0" />
                        <Metric Name="LinesOfCode" Value="1" />
                    </Metrics>
                    </Member>
                    <Member Name="LogPath.set(string) : void" File="C:\Git\coab\GoldBox.Logging\Config.cs" Line="9">
                    <Metrics>
                        <Metric Name="MaintainabilityIndex" Value="95" />
                        <Metric Name="CyclomaticComplexity" Value="1" />
                        <Metric Name="ClassCoupling" Value="0" />
                        <Metric Name="LinesOfCode" Value="1" />
                    </Metrics>
                    </Member>
                    <Member Name="SavePath.get() : string" File="C:\Git\coab\GoldBox.Logging\Config.cs" Line="10">
                    <Metrics>
                        <Metric Name="MaintainabilityIndex" Value="98" />
                        <Metric Name="CyclomaticComplexity" Value="1" />
                        <Metric Name="ClassCoupling" Value="0" />
                        <Metric Name="LinesOfCode" Value="1" />
                    </Metrics>
                    </Member>
                    <Member Name="SavePath.set(string) : void" File="C:\Git\coab\GoldBox.Logging\Config.cs" Line="10">
                    <Metrics>
                        <Metric Name="MaintainabilityIndex" Value="95" />
                        <Metric Name="CyclomaticComplexity" Value="1" />
                        <Metric Name="ClassCoupling" Value="0" />
                        <Metric Name="LinesOfCode" Value="1" />
                    </Metrics>
                    </Member>
                    <Member Name="Setup() : void" File="C:\Git\coab\GoldBox.Logging\Config.cs" Line="13">
                    <Metrics>
                        <Metric Name="MaintainabilityIndex" Value="67" />
                        <Metric Name="CyclomaticComplexity" Value="1" />
                        <Metric Name="ClassCoupling" Value="3" />
                        <Metric Name="LinesOfCode" Value="7" />
                    </Metrics>
                    </Member>
                    <Member Name="CreateIfNeeded(string) : void" File="C:\Git\coab\GoldBox.Logging\Config.cs" Line="25">
                    <Metrics>
                        <Metric Name="MaintainabilityIndex" Value="84" />
                        <Metric Name="CyclomaticComplexity" Value="2" />
                        <Metric Name="ClassCoupling" Value="1" />
                        <Metric Name="LinesOfCode" Value="2" />
                    </Metrics>
                    </Member>
                </Members>
                </Type>
            </Types>
            </Namespace>
        </Namespaces>
        </Module>
    </Modules>
    </Target>
</Targets>
</CodeMetricsReport>

我一直在努力

void Main()
{
    var xml = XElement.Load(@"C:\Git\coab\MetricResults\immer@DESKTOP-2KSR2T6 2016-05-15 05_27_14.mrx");
    XmlSerializer serializer = new XmlSerializer(typeof(Target));
    xml.Dump();
    xml.Descendants("Target")
        .Select(e=>(Target)serializer.Deserialize(e.CreateReader()))
        .Dump();
}
public class Target 
{
    [XmlAttribute]
    public string Name {get;set;}
    public List<Module> Modules {get;set;}
}
public class Module
{
    [XmlAttribute]
    public string Name {get;set;}

    [XmlAttribute]
    public string AssemblyVersion {get;set;}

    public List<Metric> Metrics {get;set;}
    public List<Namespace> Namespaces {get;set;}
}
public class Namespace
{
    [XmlAttribute]
    public string Name {get;set;}
    public List<Metric> Metrics {get;set;}
    public List<Type> Types {get;set;}
}

public class Type
{
    [XmlAttribute]
    public string Name {get;set;}
    public List<Metric> Metrics {get;set;}

}
public class Metric
{
    [XmlAttribute]
    public string Name {get;set;}

    [XmlAttribute]
    public string Value {get;set;}
}

当我到达 Type 时,我知道我可以依靠 LinqPad 将我的 Type 放在它自己独特的命名空间中,并且代码可以正常工作。但是对于我要编写的代码,我不希望它是Type,我宁愿它是MetricType 但是当我将Namespace 类中的Type 更改为MetricType 时,我回来了零结果。所以问题是我怎样才能让Namespace 看起来像这样?

public class Namespace
{
    [XmlAttribute]
    public string Name {get;set;}
    public List<Metric> Metrics {get;set;}
    public List<MetricType> Types {get;set;}
}
public class MetricType
{
    [XmlAttribute]
    public string Name {get;set;}
    public List<Metric> Metrics {get;set;}
}

【问题讨论】:

    标签: c# xml xml-deserialization


    【解决方案1】:

    序列化程序将从类型和属性名称推断元素和属性名称。如果你想要不同的名字,你必须添加属性来明确定义你想要使用的名字。

    这里需要的属性是XmlArrayItem,它指定列表中项目的名称:

    public class Namespace
    {
        [XmlAttribute]
        public string Name { get; set; }
    
        public List<Metric> Metrics { get; set; }
    
        [XmlArrayItem("Type")]
        public List<MetricType> Types { get; set; }
    }
    

    只是为了给你更多的味道,如果你想明确说明这个类中的所有名称,你需要这些属性:

    [XmlRoot("Namespace")
    public class Namespace
    {
        [XmlAttribute("Name")]
        public string Name { get; set; }
    
        [XmlArray("Metrics")]
        [XmlArrayItem("Metric")]
        public List<Metric> Metrics { get; set; }
    
        [XmlArray("Types")]
        [XmlArrayItem("Type")]
        public List<MetricType> Types { get; set; }
    }
    

    请参阅this fiddle 以获得工作演示。

    【讨论】:

    • 我查看了一堆 Xml___Attribute 并没有看到 XmlArrayXmlArrayItem 非常感谢。我最终作弊并使用 LINQ 和 Select 来解决这个问题,但我可能只是为了关闭目的而尝试一下
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-09
    • 2020-12-09
    • 2016-05-05
    相关资源
    最近更新 更多