在反序列化.NET时获取XML元素的属性

时间:2015-02-04 20:57:20

标签: c# xml vb.net serialization nested-attributes

我已经广泛搜索了这个答案,我觉得这不可能,但我想我会问。这也与VB和C#用户有关。

我有一个来自其他应用程序的XML(看起来已被序列化)。我目前已经创建了许多模仿XML结构的类,一切正常。但是,我在自己的应用程序中使用顶级类结构,以便稍后使用Reflection和Dictionaries访问属性。

这创造了几个案例,我必须挖掘类对象的层次以获得我想要的值。在许多情况下,该值只是元素的属性;在多种情况下,就在XML的顶层。我的问题是,我可以通过反序列化访问顶级类中元素的属性吗?无需创建捕获它们的嵌套/子类?

同样,这一切都适用于复杂的类结构,我只是想简化一些事情以供以后使用。这是一个非常简单的示例,但是这些情况都是我正在使用的XML文件。

以下是我尝试反序列化的XML的一个简单示例

<ParentClass name="Jeremy" role="engineer">
    <ChildClass total="10" />
</ParentClass>

这是我知道今天可以使用的类结构。但是,要访问值Total,我必须使用User.Points.Total

来调用它
<Serializable> <XmlRoot("ParentClass")> Public Class User
    <XmlAttribute("name")> Public Property UserName as String
    <XmlAttribute("role")> Public Property UserRole as String
    <XmlElement("ChildClass")> Public Property Points as Points
End Class

<Serializable> Public Class Points
    <XmlAttribute("total")> Public Property Total as String
End Class

希望是可能的,如下所示,我可以更轻松地调用User.Total。

注意我在这种情况下称它为XmlMagicalFlag。

<Serializable> <XmlRoot("ParentClass")> Public Class User
    <XmlAttribute("name")> Public Property UserName as String
    <XmlAttribute("role")> Public Property UserRole as String
    <XmlMagicalFlag("total")> Public Property Total as String
End Class

1 个答案:

答案 0 :(得分:-1)

为了简单和方便的工作,我建议您使用xsd生成实用程序xsd.exe

如果您安装了SDK,它通常位于: C:\ Program Files \ Microsoft SDKs \ Windows \\ Bin

例如,我们有一个xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<ParentClass name="Jeremy" role="engineer">
    <ChildClass total="10" />
</ParentClass>

使用命令行生成架构:

C:\ Program Files \ Microsoft SDKs \ Windows \ v6.0A \ Bin&gt; xsd.exe C:\ Docs \ test.xml

结果,现在我们有一个xsd文件 test.xsd

下一步我们从xsd文件创建类结构:

C:\ Program Files \ Microsoft SDKs \ Windows \ v6.0A \ Bin&gt; xsd.exe test.xsd / classes

之后,结果是,您有自动生成的类,带有注释,可以序列化/反序列化,例如:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", 2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class ParentClass {

    private ParentClassChildClass[] childClassField;

    private string nameField;

    private string roleField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("ChildClass",Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public ParentClassChildClass[] ChildClass {
        get {
            return this.childClassField;
        }
        set {
            this.childClassField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string name {
        get {
            return this.nameField;
        }
        set {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string role {
        get {
            return this.roleField;
        }
        set {
            this.roleField = value;
        }
    }
}

从那以后,您可以反序列化您的xml文件,并执行您想要的所有操作:

public static ParentClass Deserialize(Stream dictFileStream, XmlSerializer serializer)
{
    var reader = XmlReader.Create(dictFileStream);
    var item = (ParentClass)serializer.Deserialize(reader);
    return item;
}

用法:

using (var file = new FileStream(@"c:\Docs\test.xml", FileMode.Open))
{
    var serializer = new XmlSerializer(typeof(ParentClass));
    var parent = Deserialize(file, serializer);

    // do what you want
    parent.name = ...
    parent.ChildClass.total ...
}