我能够将以下XML解析为对象,感谢MikeH。
当我将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中:编辑 - &gt;选择性粘贴 - &gt;将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>
答案 0 :(得分:0)
您需要做的是使用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
对象包含它们的数组索引作为属性,这似乎是多余的,因为它的单元格列表中每个单元格的位置也传达了这些信息。您是否真的希望在运行时类中使用它 - 或者您是否愿意仅为序列化生成此信息?如果你更喜欢后者,你可以序列化&amp;将单元格反序列化为包含数组索引作为属性属性的代理数组,如下所示:
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);
}
}