我已经想出如何从XML数据中填充自定义类,但我遇到了一个问题。事情与我现有的填充数据的方法完美配合,直到我被抛出一点曲线球。我发送的新架构与此类似:
<ITEM_REPLY>
<TRAN_ID>1320691307345</TRAN_ID>
<REPLY_CODE>0</REPLY_CODE>
<UNIT_PRICE>8.2784</UNIT_PRICE>
<SUP_LOCS>
<SUP_LOC>
<SUP_LOC_ID>001134</SUP_LOC_ID>
<COUNTRY_ID>USA</COUNTRY_ID>
<QTY_AVL>47.000</QTY_AVL>
<ITEM_UOM>EA</ITEM_UOM>
</SUP_LOC>
<SUP_LOC>
<SUP_LOC_ID>006817</SUP_LOC_ID>
<COUNTRY_ID>USA</COUNTRY_ID>
<QTY_AVL>20.000</QTY_AVL>
<ITEM_UOM>EA</ITEM_UOM>
</SUP_LOC>
</SUP_LOCS>
<MESSAGE />
<QTY_BREAKS />
</ITEM_REPLY>
非常标准的XML架构,问题是我不确定如何用它填充我的自定义类。这就是我所拥有的:
static void Main(string[] args)
{
var order = ConvertXMLMessage<ItemReply>(request);
}
protected static T ConvertXMLMessage<T>(String xmlData) where T : class, new()
{
var xml = new XmlDocument();
xml.LoadXml(xmlData);
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
using (var xmlReader = new XmlNodeReader(xml.DocumentElement))
{
T work = (T)(serializer.Deserialize(xmlReader));
return work;
}
}
public class ItemReply
{
[XmlElement("ITEM_REPLY")]
public ItemAvlReply ITEM_REPLY { get; set; }
}
public class ItemAvlReply
{
[XmlElement("TRAN_ID")]
public string TRAN_ID { get; set; }
[XmlElement("REPLY_CODE")]
public string REPLY_CODE { get; set; }
[XmlElement("UNIT_PRICE")]
public string UNIT_PRICE { get; set; }
[XmlElement("SUP_LOCS")]
public SupplierLocations SUP_LOCS;
[XmlElement("MESSAGE")]
public string MESSAGE { get; set; }
[XmlElement("QTY_BREAKS")]
public string QTY_BREAKS { get; set; }
}
public class SupplierLocations
{
[XmlElement("SUP_LOC")]
public List<SupplierLocation> SUP_LOC;
}
public class SupplierLocation
{
[XmlElement("SUP_LOC_ID")]
public string SUP_LOC_ID { get; set; }
[XmlElement("COUNTRY_ID")]
public string COUNTRY_ID { get; set; }
[XmlElement("QTY_AVL")]
public string QTY_AVL { get; set; }
[XmlElement("ITEM_UOM")]
public string ITEM_UOM { get; set; }
}
这完全取决于List<Item>
部分。我对LINQ没有过多的经验,我不知道如何通过这个语句在我的类中声明一个子数组。我也对创建List<Item>
部分采取了不同的方法,我不知道从哪里开始。对于我需要做的事情,有没有更好的方法?有没有一个简单的解决方案我只是在LINQ中没有意识到?
答案 0 :(得分:2)
这是一种简单的方法,假设您提供的示例XML文件存在拼写错误。我假设OrderId有一个结束标记,Items
的结束标记应为/Items
。
这是我使用的xml的版本:
<Order>
<TransactionID>123</TransactionID>
<OrderID>1</OrderID>
<Items Number="2">
<Item>
<ItemName>Test</ItemName>
<Color>Red</Color>
</Item>
<Item>
<ItemName>Test1</ItemName>
<Color>Blue</Color>
</Item>
</Items>
</Order>
这里是读取/写入XML的代码:( xml变量是一个字符串)
var order = ConvertXMLMessage<Order>(xml);
WriteXMLFile<Order>(order, @"test.xml");
这里是ConvertXMLMessage和WriteXMLFile函数:
protected static T ConvertXMLMessage<T>(String xmlData) where T : class, new()
{
var xml = new XmlDocument();
xml.LoadXml(xmlData);
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T));
using (var xmlReader = new XmlNodeReader(xml.DocumentElement))
{
T work = (T)(serializer.Deserialize(xmlReader));
return work;
}
}
protected static void WriteXMLFile<T>(T item, String saveLocation) where T : class, new()
{
System.Xml.Serialization.XmlSerializer writer = new System.Xml.Serialization.XmlSerializer(typeof(T));
System.IO.StreamWriter file = new System.IO.StreamWriter(saveLocation);
writer.Serialize(file, item);
file.Close();
}
以及这里的班级结构:
public class Order
{
[XmlElement("TransactionID")]
public string TransactionId { get; set; }
[XmlElement("OrderID")]
public string OrderId { get; set; }
[XmlElement("Items")]
public ItemsContainer Items;
}
public class ItemsContainer
{
[XmlAttribute("Number")]
public Int32 Number { get; set; }
[XmlElement("Item")]
public List<Item> Items;
}
public class Item
{
[XmlElement("ItemName")]
public string ItemName { get; set; }
[XmlElement("Color")]
public string Color { get; set; }
}
正如您所注意到的,我添加了一些属性,让XML解析器知道如何在从XML转换到XML时处理该类。我还添加了另一个名为&#34; ItemsContainer&#34;只是为了保存Items标签的细节。如果你不需要&#34; Number&#34;属性,然后你可能找到一种方法来消除这一点。但是,这应该会让你朝着正确的方向前进。
我提供的示例是我通常处理这种情况的简单版本,显然可以根据您的需要进行一些改进。
修改强>
我将Item类更改为使用ItemName
而不是TransactionId
。这是我的疏忽。
编辑2
这是您需要对新发布的代码进行的更正。 Order
类在前一个示例中工作的原因是它与根XML元素匹配。您的新XML确实与基类保持一致。因此,我们需要添加更多属性才能使其工作。您也可以删除ItemReply
课程。它不需要。
所以这里是新课程:
[XmlRoot("ITEM_REPLY")]
public class ItemAvlReply
{
[XmlElement("TRAN_ID")]
public string TRAN_ID { get; set; }
[XmlElement("REPLY_CODE")]
public string REPLY_CODE { get; set; }
[XmlElement("UNIT_PRICE")]
public string UNIT_PRICE { get; set; }
[XmlElement("SUP_LOCS")]
public SupplierLocations SUP_LOCS;
[XmlElement("MESSAGE")]
public string MESSAGE { get; set; }
[XmlElement("QTY_BREAKS")]
public string QTY_BREAKS { get; set; }
}
public class SupplierLocations
{
[XmlElement("SUP_LOC")]
public List<SupplierLocation> SUP_LOC;
}
public class SupplierLocation
{
[XmlElement("SUP_LOC_ID")]
public string SUP_LOC_ID { get; set; }
[XmlElement("COUNTRY_ID")]
public string COUNTRY_ID { get; set; }
[XmlElement("QTY_AVL")]
public string QTY_AVL { get; set; }
[XmlElement("ITEM_UOM")]
public string ITEM_UOM { get; set; }
}
其他一切应该保持不变。将XML解析/转换为类应该无需任何更改。