【问题标题】:XML serialization and why am I ending up with an ended element?XML 序列化以及为什么我以一个结束的元素结束?
【发布时间】:2020-05-18 11:33:40
【问题描述】:

我在这里做错了什么?

测试 XML:

<?xml version="1.0" encoding="utf-8"?>
<CutToolsDatabase xmlns="https//www.trucklesoft.co.uk/cuttools">
  <MaterialGroup>
    <Name>White Back Folding Boxboard - GC1</Name>
    <Material>
      <Name>296Um</Name>
      <Text>
        <Value>Carte Lumina 640x900 200 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>345Um</Name>
      <Text>
        <Value>Carte Lumina 450x640 230 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>368Um</Name>
      <Text>
        <Value>Opus Card 720x1020 260 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>375Um</Name>
      <Text>
        <Value>Carte Lumina 720x1020 250 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>398Um</Name>
      <Text>
        <Value>Opus Card 720x1020 280 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>405Um</Name>
      <Text>
        <Value>Carte Lumina 450x640 270 Gsm</Value>
        <Value>Incada Silk 450x640 260 Gsm </Value>
      </Text>
    </Material>
    <Material>
      <Name>445Um</Name>
      <Text>
        <Value>Incada Silk 450x640 280 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>450Um</Name>
      <Text>
        <Value>Carte Lumina 450x640 300 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>485Um</Name>
      <Text>
        <Value>Incada Silk 450x640 300 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>495Um</Name>
      <Text>
        <Value>Carte Lumina 450x640 330 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>540Um</Name>
      <Text>
        <Value>Incada Silk 520x720 325 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>570Um</Name>
      <Text>
        <Value>Carte Lumina 450x640 380 Gsm</Value>
      </Text>
    </Material>
    <Material>
      <Name>590Um</Name>
      <Text>
        <Value>Incada Silk 450x640 350 Gsm</Value>
      </Text>
    </Material>
  </MaterialGroup>
</CutToolsDatabase>

我为此 XML 创建的类:

using System.Collections.Generic;
using System.Xml.Serialization;

namespace CutTools.MaterialsDatabase
{
    [XmlRoot(ElementName = "CutToolsDatabase", Namespace = "https://www.trucklesoft.co.uk/cuttools")]
    public class CutToolsDatabase
    {
        [XmlArray]
        [XmlArrayItem(ElementName = "MaterialGroup")]
        public List<CutToolsDatabaseMaterialGroup> MaterialGroup;

        public CutToolsDatabase()
        {
            MaterialGroup = new List<CutToolsDatabaseMaterialGroup>();
        }
    }

    public class CutToolsDatabaseMaterialGroup
    {
        [XmlElement]
        public string Name;

        [XmlArray]
        [XmlArrayItem(ElementName = "Material")]
        public List<CutToolsDatabaseMaterial> Material;

        public CutToolsDatabaseMaterialGroup()
        {
            Name = "";
            Material = new List<CutToolsDatabaseMaterial>();
        }
    }

    public class CutToolsDatabaseMaterial
    {
        [XmlElement]
        public string Name;

        [XmlArray]
        [XmlArrayItem(ElementName = "Value")]  
        public List<string> Text;

        public CutToolsDatabaseMaterial()
        {
            Name = "";
            Text = new List<string>();
        }
    }
}

我用来加载 XML 文件的代码:

private bool ReadMaterialsData(ref CutToolsDatabase docMaterialsDB)
{
    bool bRead = false;
    try
    {
        System.Reflection.Module mod = GetType().Module;
        string strPath = Path.GetDirectoryName(mod.FullyQualifiedName);
        XmlSerializer x = new XmlSerializer(docMaterialsDB.GetType());
        Bricscad.ApplicationServices.Application.ShowAlertDialog(Path.Combine(strPath, "Materials.xml"));
        using (StreamReader reader = new StreamReader(Path.Combine(strPath, "Materials.xml")))
        {
            docMaterialsDB = (CutToolsDatabase)x.Deserialize(reader);

            bRead = true;
        }
    }
    catch (System.Exception ex)
    {

    }

    return bRead;
}

所以我为什么要这样尝试:

CutToolsDatabase _docMaterialsDB = new CutToolsDatabase();
ReadMaterialsData(ref _docMaterialsDB);
_AcAp.Application.ShowAlertDialog(_docMaterialsDB.MaterialGroup.Count.ToString());

显示的结果是0,怎么回事?我可以手动读取 xml 文件并使用选择路径,所以我做错了什么?

我编写了一个例程来添加一些元素并将其保存到 XML。为什么会这样?

<?xml version="1.0" encoding="utf-8"?>
<CutToolsDatabase xmlns="https://www.trucklesoft.co.uk/cuttools">
  <MaterialGroup>
    <MaterialGroup>
      <Name>Andrew Group</Name>
      <Material>
        <Material>
          <Name>Andrew Material</Name>
          <Text>
            <Value>Andrew Value</Value>
          </Text>
        </Material>
      </Material>
    </MaterialGroup>
  </MaterialGroup>
</CutToolsDatabase>

【问题讨论】:

    标签: c# xml xml-serialization


    【解决方案1】:

    [XmlArray]+[XmlArrayItem] 代表双重嵌套场景 - 比如:

    <Foos>
       <Foo/>
       <Foo/>
       <Foo/>
    </Foos>
    

    但是,在您的情况下,它们都是单独嵌套的,因此:您应该改用[XmlElement]

    [XmlRoot(ElementName = "CutToolsDatabase", Namespace = "https//www.trucklesoft.co.uk/cuttools")]
    public class CutToolsDatabase
    {
        [XmlElement(ElementName = "MaterialGroup")]
        public List<CutToolsDatabaseMaterialGroup> MaterialGroups { get; }
    
        public CutToolsDatabase()
        {
            MaterialGroups = new List<CutToolsDatabaseMaterialGroup>();
        }
    }
    
    public class CutToolsDatabaseMaterialGroup
    {
        [XmlElement]
        public string Name { get; set; }
    
        [XmlElement(ElementName = "Material")]
        public List<CutToolsDatabaseMaterial> Material;
    
        public CutToolsDatabaseMaterialGroup()
        {
            Name = "";
            Material = new List<CutToolsDatabaseMaterial>();
        }
    }
    
    public class CutToolsDatabaseMaterial
    {
        [XmlElement]
        public string Name { get; set; }
    
        [XmlElement]
        public Text Text { get; set; }
    
        public CutToolsDatabaseMaterial()
        {
            Name = "";
            Text = new Text();
        }
    }
    
    public class Text
    {
        [XmlElement]
        public string Value { get; set; }
    }
    

    【讨论】:

    • 谢谢,命名空间有什么问题?此外,还可以有一个“值”对象列表。
    • @AndrewTruckle 命名空间需要在本地进行调整,但是......也许是复制/粘贴错误;至于Value - 很好,那就用一个列表来代替
    • 我可以确认正在写入文件OK。但它似乎没有在我的主文件中读取。它仍然是 0。为什么会这样?
    • @AndrewTruckle 哈哈,毕竟是 xml 命名空间; 非常非常仔细地看
    • @AndrewTruckle 它需要匹配 xml; xml 没有 :
    【解决方案2】:

    以下代码经过测试。 XML 序列化一个 XmlArray 是两个 XML 标记(父和子)。您只有一个标签,因此您需要改用 XmlElement。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using System.Xml;
    using System.Xml.Serialization;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.xml";
            static void Main(string[] args)
            {
                XmlReader reader = XmlReader.Create(FILENAME);
    
                XmlSerializer serializer = new XmlSerializer(typeof(CutToolsDatabase));
    
                CutToolsDatabase db = (CutToolsDatabase)serializer.Deserialize(reader);
    
            }
        }
        [XmlRoot(ElementName = "CutToolsDatabase", Namespace = "https//www.trucklesoft.co.uk/cuttools")]
        public class CutToolsDatabase
        {
            public CutToolsDatabaseMaterialGroup MaterialGroup;
        }
    
        public class CutToolsDatabaseMaterialGroup
        {
            [XmlElement]
            public string Name;
    
            [XmlElement(ElementName = "Material")]
            public List<CutToolsDatabaseMaterial> Material;
    
            public CutToolsDatabaseMaterialGroup()
            {
                Name = "";
                Material = new List<CutToolsDatabaseMaterial>();
            }
        }
    
        public class CutToolsDatabaseMaterial
        {
    
            public string Name;
    
            [XmlElement(ElementName = "Text")]
            public List<Text> Text;
    
            public CutToolsDatabaseMaterial()
            {
                Name = "";
            }
        }
        public class Text
        {
            public string Value { get; set; }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      相关资源
      最近更新 更多