【问题标题】:XML parse it into a collection objectXML 将其解析为一个集合对象
【发布时间】:2014-11-19 18:56:00
【问题描述】:

感谢 MikeH,我能够将以下 XML 解析为一个对象。

当我将 XML 文件解析为对象时,它只会将最后一行填充到对象中。我如何将所有行解析为一个集合对象。这些行应该填充到一个集合中。在这种情况下,所有 5 条记录都应该在集合中,而不仅仅是最后一条记录 ()。我花了大部分时间,我一定错过了如何将所有行放入对象中。

  - <ROW>
    <CELL INDEX="0">033331111</CELL> 
    <CELL INDEX="1">Agency 5 LTD</CELL> 
    <CELL INDEX="2">14 Some AVENUE North Brook, FL 65432 3827</CELL> 
    <CELL INDEX="3">A</CELL> 
    <CELL INDEX="4">4412034564</CELL> 
    <CELL INDEX="5" /> 
    <CELL INDEX="6">A - Active</CELL> 
    <CELL INDEX="7">6/1/2008 12:00:00 AM</CELL> 
    </ROW>

使用 Visual Studio 2012 或更高版本: 将 XML 复制到剪贴板 在 Visual Studio 中:编辑 --> 选择性粘贴 --> 将 XML 粘贴为类 然后,您需要将 XML 中的数据序列化到新创建的类中以创建新对象:

var myObject = LoadFromXmlString<DATA_PROVIDERS>(xmlData);

public static T LoadFromXmlString<T>(string xml)
{
  T retval = default(T);
  try
  {
    XmlSerializer s = new XmlSerializer(typeof(T));
    MemoryStream ms = new MemoryStream(ASCIIEncoding.Default.GetBytes(xml));
    retval = (T)s.Deserialize(ms);
    ms.Close(); 
  }
  catch (Exception ex)
  {
    ex.Data.Add("Xml String", xml);
    throw new Exception("Error loading from XML string.  See data.", ex);
  }
  return retval;

}


<?xml version="1.0" encoding="UTF-8" ?> 
-<DATA_PROVIDERS UID="Providers|REP" FORCE_REFRESH="FALSE" DATA_PROVIDER="" FORMATTED="FALSE" REFRESH="TRUE">
 -<DATA_PROVIDER NAME="Prov" SOURCE="Provider" DATE="11/18/2014" DURATION="9s" REFRESH="TRUE" CUBE="1">
  <COLUMN INDEX="0" ID="119" TYPE="String" FORMAT="">Prov ID</COLUMN> 
  <COLUMN INDEX="1" ID="118" TYPE="String" FORMAT="">Prov Name</COLUMN> 
  <COLUMN INDEX="2" ID="113" TYPE="String" FORMAT="">Address Info</COLUMN> 
  <COLUMN INDEX="3" ID="110" TYPE="String" FORMAT="">Enroll Status Code</COLUMN> 
  <COLUMN INDEX="4" ID="119" TYPE="String" FORMAT="">Phone</COLUMN> 
  <COLUMN INDEX="5" ID="110" TYPE="String" FORMAT="">Fax</COLUMN> 
  <COLUMN INDEX="6" ID="109" TYPE="String" FORMAT="">Provider Status</COLUMN> 
  <COLUMN INDEX="7" ID="150" TYPE="Date" FORMAT="m/d/yyyy h:mm:ss am/pm">Provider Start Date</COLUMN> 
  - <ROW>
    <CELL INDEX="0">004042111</CELL> 
    <CELL INDEX="1">CONTOSO West INC</CELL> 
    <CELL INDEX="2">1234 Random Rd. SOMECITY, ZZ 12345 9876</CELL> 
    <CELL INDEX="3">F</CELL> 
    <CELL INDEX="4">5555551234123</CELL> 
    <CELL INDEX="5">5555551234</CELL> 
    <CELL INDEX="6">F - Agency Action</CELL> 
    <CELL INDEX="7">5/31/2011 12:00:00 AM</CELL> 
    </ROW>
  - <ROW>
    <CELL INDEX="0">004011117</CELL> 
    <CELL INDEX="1">CONTOSO North INC</CELL> 
    <CELL INDEX="2">4321 Random Rd. SOMECITY, ZZ 12345 9876</CELL> 
    <CELL INDEX="3">F</CELL> 
    <CELL INDEX="4">5555551234123</CELL> 
    <CELL INDEX="5">5555551234</CELL> 
    <CELL INDEX="6">F - Agency Action</CELL> 
    <CELL INDEX="7">5/31/2011 12:00:00 AM</CELL> 
    </ROW>
  - <ROW>
    <CELL INDEX="0">033337111</CELL> 
    <CELL INDEX="1">Agency 3 INC</CELL> 
    <CELL INDEX="2">200 street 5F Cityabc, NY 12033</CELL> 
    <CELL INDEX="3">A</CELL> 
    <CELL INDEX="4">2128545555</CELL> 
    <CELL INDEX="5" />
    <CELL INDEX="6">A - Active</CELL> 
    <CELL INDEX="7">10/27/2003 12:00:00 AM</CELL> 
    </ROW>
  - <ROW>
    <CELL INDEX="0">033334111</CELL> 
    <CELL INDEX="1">Agency 4 LLC</CELL> 
    <CELL INDEX="2">419 street Town, CT 17033 3945</CELL> 
    <CELL INDEX="3">U</CELL> 
    <CELL INDEX="4" /> 
    <CELL INDEX="5">7172304056</CELL> 
    <CELL INDEX="6">X - Did Not Re-enroll</CELL> 
    <CELL INDEX="7">2/24/2009 12:00:00 AM</CELL> 
    </ROW>
  - <ROW>
    <CELL INDEX="0">033331111</CELL> 
    <CELL INDEX="1">Agency 5 LTD</CELL> 
    <CELL INDEX="2">14 Some AVENUE North Brook, FL 65432 3827</CELL> 
    <CELL INDEX="3">A</CELL> 
    <CELL INDEX="4">4412034564</CELL> 
    <CELL INDEX="5" /> 
    <CELL INDEX="6">A - Active</CELL> 
    <CELL INDEX="7">6/1/2008 12:00:00 AM</CELL> 
    </ROW>
 </DATA_PROVIDER>
</DATA_PROVIDERS>

【问题讨论】:

    标签: c# asp.net xml parsing object


    【解决方案1】:

    您需要做的是使用XmlElement("CELLS") 属性标记您的Cells 集合,以通知XmlSerializer 该集合应序列化为一系列同名元素,而不是具有嵌套子元素的单个元素,像这样:

    public class Cell
    {
        [XmlText]
        public string Text { get; set; }
    
        [XmlAttribute("INDEX")]
        public int Index { get; set; }
    }
    
    [XmlRoot("ROW")]
    public class Row
    {
        [XmlElement("CELL")]
        public List<Cell> Cells { get; set; }
    }
    

    此外,我注意到您的 Cell 对象包含它们的数组索引作为属性,这似乎是多余的,因为每个单元格在其单元格列表中的位置也传达了此信息。您是否真的希望在您的运行时类中使用该信息——或者您更愿意生成这些信息仅用于序列化?如果您更喜欢后者,您可以将单元格序列化和反序列化为代理数组,其中包含数组索引作为属性属性,如下所示:

    public class Cell 
    {
        public Cell() {}
    
        public Cell(Cell other)
        {
            this.Text = other.Text;
        }
    
        [XmlText]
        public string Text { get; set; }
    }
    
    public class XmlCell : Cell // For serialization
    {
        public XmlCell() : base() {}
    
        public XmlCell(Cell other, int index) : base(other)
        {
            this.Index = index;
        }
    
        [XmlAttribute("INDEX")]
        public int Index { get; set; }
    }
    
    [XmlRoot("ROW")]
    public class Row
    {
        List<Cell> cells;
    
        [XmlIgnore]
        public List<Cell> Cells
        {
            get
            {
                if (cells == null)
                    Interlocked.CompareExchange(ref cells, new List<Cell>(), null);
                return cells;
            }
        }
    
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [DebuggerBrowsable(DebuggerBrowsableState.Never)]
        [XmlElement("CELL")]
        public XmlCell[] XmlCells // proxy array for serialization.
        {
            get
            {
                var xmlCells = new XmlCell[Cells.Count];
                for (int iCell = 0; iCell < xmlCells.Length; iCell++)
                    xmlCells[iCell] = new XmlCell(Cells[iCell], iCell);
                return xmlCells;
            }
            set
            {
                Cells.Clear();
                foreach (var xmlCell in value)
                {
                    Cells.EnsureCount(xmlCell.Index + 1);
                    Cells[xmlCell.Index] = new Cell(xmlCell);
                }
            }
        }
    }
    

    最后是几个扩展方法:

    public static class ListExtensions
    {
        public static void Resize<T>(this List<T> list, int count)
        {
            if (list == null || count < 0)
                throw new ArgumentException();
            int oldCount = list.Count;
            if (count > oldCount)
            {
                list.Capacity = count;
                for (int i = oldCount; i < count; i++)
                    list.Add(default(T));
            }
            else if (count < oldCount)
            {
                for (int i = oldCount - 1; i >= count; i--)
                    list.RemoveAt(i);
            }
        }
    
        public static void EnsureCount<T>(this List<T> list, int count)
        {
            if (list == null || count < 0)
                throw new ArgumentException();
            if (count > list.Count)
                list.Resize(count);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-08-21
      • 2021-05-16
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多