【问题标题】:C# deserializing nested elements with only one itemC# 反序列化只有一项的嵌套元素
【发布时间】:2014-05-08 20:06:39
【问题描述】:

我使用 C# 反序列化 XML 文件。我的 XML 文件格式为:

<Produced_by >
    <Producing_Unit>
        <Unit ID="" Name=""/>
    </Producing_Unit>
</Produced_by>

反序列化我想删除中间人Producing_Unit。因为 Produced_by 将始终只包含一个子元素 Producing_Unit 来指定 Unit。 我对如何实施的最初想法不起作用:

public class Unit
{
    public string Name { get; set; }
    public string ID { get; set; }
}

public class Produced_by
{
    [XmlElement("Producing_Unit")]
    [XmlElement("Unit")]
    public Unit Unit { get; set; }
}

可以使用 [XmlArray("Producing_Unit"), XmlArrayItem("Unit")] 解决 然后让 Produced_by 包含:public List {get;set;}。但这不是我想要的。

【问题讨论】:

  • 尝试将 XMLElement 属性放在 Unit 类中,并在其属性之上。
  • AFAIK,不可能将 XML 与“Producing_Unit”标签一起使用,而是放弃匹配的具有标准属性的 Producing_Unit 类,而不是实现 IXmlSerializable interface. 你最好的选择是将你的来自序列化层的应用程序/业务逻辑。保持您的序列化简单并匹配您的 XML 模式,然后简单地转换为/从该数据模型和更清晰的数据模型(不带 Producing_Unit)供您的应用程序的其余部分使用。
  • @Ramie 你能举个例子吗?

标签: c# xml nested xml-serialization deserialization


【解决方案1】:

据我所知,不可能将 XML 与“Producing_Unit”标签一起使用,而是放弃具有标准属性的匹配 Producing_Unit 类,而不是实现 IXmlSerializable interface. 您最好的选择是分离您的应用程序/来自序列化层的业务逻辑。

保持您的序列化数据模型简单并匹配您的 XML 架构(这意味着包括包装 Producing_Unit 类),然后简单地转换为/从该数据模型和更清晰的数据模型(不包括 Producing_Unit)其余部分您可以使用的应用程序。


编辑:这是使用IXmlSerializable 接口的实现。老实说,我只是把它扔掉了,不知道它是否适用于所有情况。

public class Unit
{
    public string Name { get; set; }

    public string ID { get; set; }
}

public class Produced_by : IXmlSerializable
{
    public Unit Unit { get; set; }

    public void WriteXml (XmlWriter writer)
    {
        writer.WriteStartElement("Produced_by");
        writer.WriteStartElement("Producing_Unit");
        writer.WriteStartElement("Unit");
        writer.WriteAttributeString("ID", this.Unit.ID);
        writer.WriteAttributeString("Name", this.Unit.Name);
        writer.WriteEndElement();
        writer.WriteEndElement();
        writer.WriteEndElement();
    }

    public void ReadXml (XmlReader reader)
    {
        while (reader.Read())
        {
            if (reader.Name == "Unit")
            {
                this.Unit = new Unit()
                {
                    Name = reader.GetAttribute("Name"),
                    ID = reader.GetAttribute("ID")
                };

                break;
            }
        }
    }

    public XmlSchema GetSchema()
    {
        return(null);
    }
}

我怀疑我的阅读方式很差,但这在我的本地测试中有效。不过,我仍然建议将您的应用程序和序列化问题分开,并避免编写这样的实现。

【讨论】:

  • 我有一个想要反序列化的 XML 文件,而不是相反。
  • @bjar-bjar:啊,所以您发布的第一个 XML 示例(带有包装的“Producing_Unit”标签)是您想要使用的固定 XML,但您不想要求拥有第三个中间人Producing_Unit class?
  • 这正是我的问题。
  • @bjar-bjar:我编辑了我的答案。抱歉,我认为使用内置的 XML 序列化属性无法实现这一点。
  • @bjar-bjar:我再次编辑了我的答案;我已经包含了IXmlSerializable 的工作实现。我仍然不推荐使用它,但是在我的本地测试中它可以正常工作。
【解决方案2】:

你可以试试这个:

public class Unit
{
    public string Name { get; set; }
    public string ID { get; set; }
}

public class Producing_Unit
{
    public Unit Unit { get; set; }
}

public class Produced_by
{
    private Producing_Unit producing_unit;

    public Producing_Unit Producing_Unit //This can't be auto-implemented since can write to properties of properties.
    { 
        get { return producing_Unit; } 
        set { producing_Unit = value; }
    }

    [XmlIgnoreAttribute]
    public Unit Unit
    {
        get { return producing_Unit.Unit; }
        set { producing_Unit.Unit = value; }
    }
}

是的,它并没有摆脱“中间人”,但你可以忽略它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多