c# - < Material xmlns ='x' > 不是预期的

标签 c# xml deserialization hierarchical-data xml-deserialization

我正在尝试使用以下方法反序列化分层 xml 文件

    public static T Deserialize<T>(this string serializedObj) where T : class
    {
        XmlSerializer xs = new XmlSerializer(typeof(T));
        T result;

        using (TextReader reader = new StringReader(serializedObj))
            result = xs.Deserialize(reader) as T;

        return result;
    }

但他一直对 xml 文件中存在架构引用这一事实感到困惑,而我不知道出了什么问题。我尝试反序列化为一个对象,但即使如此他仍然失败。

尝试反序列化 xml 的函数如下

    public static void RecieveAndSaveXml(string fullPath, string basePath, string fileName)
    {
        if (File.Exists(fullPath))
        {
            StreamReader reader = new StreamReader(fullPath);
            string xmlString = reader.ReadToEnd();
            Material material = xmlString.Deserialize<Material>();

            //Conversion to dataobject goes here

            reader.Close();
        }
    }

我试图反序列化的类

[Serializable]
[XmlRoot("Material")]
public class Material
{
    public Material() { }

    [XmlAttribute("MatNr")]
    public string MatNr { get; set; }
    [XmlAttribute("MatDescrEN")]
    public string MatDescrEN { get; set; }
    [XmlAttribute("MatDescrNL")]
    public string MatDescrNL { get; set; }
    [XmlAttribute("MatDescrFR")]
    public string MatDescrFR { get; set; }
    [XmlAttribute("OldMatNr")]
    public string OldMatNr { get; set; }
    [XmlAttribute("UoM")]
    public string UoM { get; set; }
    [XmlAttribute("MatGroupCode")]
    public string MatGroupCode { get; set; }
    [XmlAttribute("Extract")]
    public decimal Extract { get; set; }
    [XmlArray("AdditionalData"), XmlArrayItem(ElementName = "AddDataRecord", Type = typeof(AddDataRecord))]
    public AddDataRecord[] AdditionalData { get; set; }
    [XmlArray("PlantData"), XmlArrayItem(ElementName = "PlantDataRecord", Type = typeof(PlantDataRecord))]
    public PlantDataRecord[] PlantData { get; set; }
}

[Serializable]
[XmlRoot("AddDataRecord")]
public class AddDataRecord
{
    [XmlAttribute("UoMDenom")]
    public int UoMDenom { get; set; }
    [XmlAttribute("UoMAlt")]
    public string UoMAlt { get; set; }
    [XmlAttribute("UoMNum")]
    public int UoMNum { get; set; }
    [XmlAttribute("UoMBase")]
    public string UoMBase { get; set; }
}

[Serializable]
[XmlRoot("PlantDataRecord")]
public class PlantDataRecord
{
    [XmlAttribute("Plant")]
    public string Plant { get; set; }
    [XmlAttribute("Recipient")]
    public string Recipient { get; set; }
    [XmlAttribute("Status")]
    public string Status { get; set; }
}

}

和 xml

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Materials xmlns:ns0="www.foo.be/foo/">
<Material>
    <MatNr>000000000050165478</MatNr>
    <MatDescrEN>KEG CAP GREEN PR JUP NA 1/2008</MatDescrEN>
    <MatDescrNL></MatDescrNL>
    <MatDescrFR></MatDescrFR>
    <OldMatNr>000000000000216505</OldMatNr>
    <UoM>PCE</UoM>
    <MatGroupCode>020506</MatGroupCode>
    <Extract></Extract>
    <AdditionalData>
        <AddDataRecord>
            <UoMDenom>1</UoMDenom>
            <UoMAlt>PCE</UoMAlt>
            <UoMNum>1</UoMNum>
            <UoMBase>PCE</UoMBase>
        </AddDataRecord>
    </AdditionalData>
    <PlantData>
        <PlantDataRecord>
            <Plant>BE01</Plant>
            <Recipient></Recipient>
            <Status>99</Status>
        </PlantDataRecord>
    </PlantData>
</Material>
</ns0:Materials>

所以我尝试过的是

  • 将嵌套类放在注释中
  • 反序列化为对象
  • 更改列表类型
  • 使用 XmlArrayItem 将注释从 XmlAttribute 更改为 XmlArray
  • 添加了 XmlRootItems

所以我不知道接下来要尝试什么,这就是我在这里发帖的原因。提前致谢

最佳答案

与提供的 XML 文件相比,您的类存在一些问题:

  • 所有属性都是示例 xml 中的元素,但它们在 C# 类中具有 XmlAttribute
  • 您有一个不可为 null 的十进制值 (Extract),其对应的 xml 元素为空。如果这是一个有效的情况,您需要以某种方式处理这个问题。
  • 您的 xml 指示 Material 的集合,但您尝试将其反序列化为 Material 的单个实例。

更新的代码:

[Serializable]
[XmlRoot("Material")]
public class Material
{
    public Material() { }

    [XmlElement("MatNr")]
    public string MatNr { get; set; }
    [XmlElement("MatDescrEN")]
    public string MatDescrEN { get; set; }
    [XmlElement("MatDescrNL")]
    public string MatDescrNL { get; set; }
    [XmlElement("MatDescrFR")]
    public string MatDescrFR { get; set; }
    [XmlElement("OldMatNr")]
    public string OldMatNr { get; set; }
    [XmlElement("UoM")]
    public string UoM { get; set; }
    [XmlElement("MatGroupCode")]
    public string MatGroupCode { get; set; }
    [XmlElement("Extract")]
    public String ExtractString { get; set; }
    [XmlIgnore]
    public decimal Extract
    {
        get { return String.IsNullOrWhiteSpace(this.ExtractString) ? 0M : decimal.Parse(this.ExtractString); }
        set { this.ExtractString = this.Extract.ToString(CultureInfo.InvariantCulture); }
    }
    [XmlArray("AdditionalData"), XmlArrayItem(ElementName = "AddDataRecord", Type = typeof(AddDataRecord))]
    public AddDataRecord[] AdditionalData { get; set; }
    [XmlArray("PlantData"), XmlArrayItem(ElementName = "PlantDataRecord", Type = typeof(PlantDataRecord))]
    public PlantDataRecord[] PlantData { get; set; }
}

[Serializable]
[XmlRoot("AddDataRecord")]
public class AddDataRecord
{
    [XmlElement("UoMDenom")]
    public int UoMDenom { get; set; }
    [XmlElement("UoMAlt")]
    public string UoMAlt { get; set; }
    [XmlElement("UoMNum")]
    public int UoMNum { get; set; }
    [XmlElement("UoMBase")]
    public string UoMBase { get; set; }
}

[Serializable]
[XmlRoot("PlantDataRecord")]
public class PlantDataRecord
{
    [XmlElement("Plant")]
    public string Plant { get; set; }
    [XmlElement("Recipient")]
    public string Recipient { get; set; }
    [XmlElement("Status")]
    public string Status { get; set; }
}

[XmlRoot("Materials", Namespace = "www.foo.be/foo/")]
[Serializable]
public class MaterialCollection
{
   [XmlElement("Material", Namespace="")]
   public List<Material> Materials { get; set; }
}

然后你需要使用

MaterialCollection materials = xmlString.Deserialize<MaterialCollection>();

关于c# - < Material xmlns ='x' > 不是预期的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23423244/

相关文章:

c# - 从资源加载 XML

xml - 是Dart Server还是执行Xsl转换的浏览器?

android:方向改变自定义 View , View 不改变

c# - Cordova - 根据地理位置检测用户国家

c# - 如何在 ISO C++ 中定义或实现 C# 属性?

java - 反序列化Java数据结构中的文本

java - Jackson - BeanDeserializerBase

java - 无法在 Jackson 中使用 JsonParser 反序列化

c# - 在哪里放置实现相同接口(interface)的多个类所需的通用逻辑?

c# - 显示自定义控件的自定义图标?