用c#读取XML并返回编辑后的事务
本文关键字:编辑 事务 返回 读取 XML | 更新日期: 2023-09-27 17:49:33
我使用VS中的功能来创建一个定义我的输入事务的类。该代码是读取XML事务的套接字服务。我需要更改交易信息并返回。每个事务有一个RESULT节点可以出现x次,所以我需要遍历这些节点。我的问题是我不知道如何获取信息来替代它。RESULT节点中有3个不同的组节点,自动生成的类将其定义如下:
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class RATE_SHOPRESULT
{
private object[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("COMMON", typeof(RATE_SHOPRESULTCOMMON))]
[System.Xml.Serialization.XmlElementAttribute("PACKAGE", typeof(RATE_SHOPRESULTPACKAGE))]
[System.Xml.Serialization.XmlElementAttribute("SERVICE", typeof(string))]
public object[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
}
要了解这一点,我可以实例化transaction.RESULTS[0].Items[0]
,但我如何定义类型之后?服务定义了我需要更改的内容,需要更改的单个数据要么在公共数据组中,要么在包组中,这取决于服务。
下面是一个XML的例子:
<RATE_SHOP> <COMPANY_CODE>XXX</COMPANY_CODE> <RESULTS> <RESULT> <COMMON> <BASE>15.91</BASE> <SPECIAL>1.58</SPECIAL> <DISCOUNT>5.14</DISCOUNT> <TOTAL>12.35</TOTAL> <BILLED_WEIGHT>20</BILLED_WEIGHT> <SHIPPER>LOMO_GEORGIA</SHIPPER> <ZONE>4</ZONE> <FUEL_SURCHARGE>0.53</FUEL_SURCHARGE> </COMMON> <PACKAGE> <OVERSIZE_INDICATOR>4</OVERSIZE_INDICATOR> </PACKAGE> <SERVICE>BWTI_FXRS.SP.SM</SERVICE> </RESULT> </RESULTS> </RATE_SHOP>
RATE_SHOPRESULT
类对应<RESULT>
元素
由于没有XSD, xml到c#的转换器不知道元素<COMMON>
、<PACKAGE>
和<SERVICE>
可能在<RESULT>
元素中出现多少次,以及以什么顺序出现。因此,它自动生成一个object
的多态数组,称为Item
,其中可能包含与这些元素对应的任意数量的类型。
然而,作为开发人员,我们可以合理地假设每个<RESULT>
元素将包含每个子元素的不超过一个。在这种情况下,您可以手动定义RATE_SHOPRESULT
,如下所示:
public partial class RATE_SHOPRESULT
{
[System.Xml.Serialization.XmlElementAttribute("COMMON")]
public RATE_SHOPRESULTCOMMON Common { get; set; }
[System.Xml.Serialization.XmlElementAttribute("PACKAGE")]
public RATE_SHOPRESULTPACKAGE Package { get; set; }
[System.Xml.Serialization.XmlElementAttribute("SERVICE")]
public string Service { get; set; }
}
如果您想保持自动定义类的通用性,您需要测试数组中每个条目的类型。例如,下面的代码和扩展方法过滤Items
数组中每种类型的项,返回这些项及其数组索引:
public static class PolymorphicEnumerableExtensions
{
public static IEnumerable<KeyValuePair<int, TResult>> OfIndexAndType<TResult>(this IEnumerable source)
{
if (source == null)
throw new ArgumentNullException();
return OfIndexAndTypeIterator<TResult>(source);
}
static IEnumerable<KeyValuePair<int, TResult>> OfIndexAndTypeIterator<TResult>(IEnumerable source)
{
int i = 0;
foreach (object obj in source)
{
if (obj is TResult)
yield return new KeyValuePair<int, TResult>(i, (TResult)obj);
i++;
}
}
}
然后:
var commons = transaction.RESULTS[0].Items.OfIndexAndType<RATE_SHOPRESULTCOMMON>();
var packages = transaction.RESULTS[0].Items.OfIndexAndType<RATE_SHOPRESULTPACKAGE>();
var services = transaction.RESULTS[0].Items.OfIndexAndType<string>();
或者,初始化一个新结果,如:
var result = new RATE_SHOPRESULT { Items = new object[] { new RATE_SHOPRESULTCOMMON { /* Fill in properties */ }, new RATE_SHOPRESULTPACKAGE { /* Fill in properties */ }, "service name" } };