xsd.exe生成的c#在一个数组中包含多个元素
我有一组XML模式文件提供给我。我无法更改XML,因为它们有时会更新。我正在使用xsd.exe将模式文件转换为生成的c#代码。我不能使用任何第三方工具。其中一个XML架构文件的一部分如下所示:xsd.exe生成的c#在一个数组中包含多个元素,c#,xml,xsd,C#,Xml,Xsd,我有一组XML模式文件提供给我。我无法更改XML,因为它们有时会更新。我正在使用xsd.exe将模式文件转换为生成的c#代码。我不能使用任何第三方工具。其中一个XML架构文件的一部分如下所示: <xs:complexType name="LocationType"> <xs:choice minOccurs="1" maxOccurs="1"> <xs:element name="LocNum" minOccurs="1" maxOccurs="1" t
<xs:complexType name="LocationType">
<xs:choice minOccurs="1" maxOccurs="1">
<xs:element name="LocNum" minOccurs="1" maxOccurs="1" type="xs:string" />
<xs:sequence>
<xs:element name="Name" minOccurs="0" maxOccurs="1" type="xs:string" />
<xs:element name="Address" minOccurs="0" maxOccurs="1" type="xs:string" />
<xs:element name="City" minOccurs="1" maxOccurs="1" type="xs:string" />
<xs:element name="State" minOccurs="0" maxOccurs="1">
</xs:sequence>
</xs:choice>
</xs:complexType>
该模式所说的是,如果某个外部类型包含类型为
LocationType
的元素,则可以在其中找到
1) 子元素
,或
2) 这些子元素按顺序排列:
,属性,在本例中为ItemsElementName
。此数组中的条目必须与项
数组1-1对应。它通过ItemsChoiceType
枚举记录在Items
数组的每个索引中反序列化的元素的名称,其枚举名称必须与装饰Items
数组的属性中的名称相匹配。这使得多态数据的具体选择是已知的
因此,要完善LocationType
类的实现,您需要确定给定的LocationType
是直接的还是间接的;拿出各种财产;对于每种类型(直接或间接),设置所有必需的数据
这是一个原型。(您的问题中没有包含LocationTypeState
的定义,因此我将其视为一个字符串):
public分部类LocationType
{
公共位置类型(){}
公共位置类型(字符串locNum)
{
SetIndirectLocation(locNum);
}
公共位置类型(字符串名称、字符串地址、字符串城市、字符串状态)
{
SetDirectLocation(名称、地址、城市、州);
}
公共广播是间接定位的
{
得到
{
返回Array.IndexOf(ItemsElementName,ItemsChoiceType.LocNum)>=0;
}
}
公共字符串地址{get{return(string)XmlPolymorphicCarrayHelper.GetItem(Items,ItemsElementName,ItemsChoiceType.Address);}
公共字符串LocNum{get{return(string)xmlmorphicalarayhelper.GetItem(Items,ItemsElementName,ItemsChoiceType.LocNum);}
//其他需要的属性。
public void SetIndirectLocation(字符串locNum)
{
if(string.IsNullOrEmpty(locNum))
抛出新ArgumentException();
object[]newItems=新对象[]{locNum};
ItemsChoiceType[]newItemsElementName=new ItemsChoiceType[]{ItemsChoiceType.LocNum};
this.Items=newItems;
this.ItemsElementName=newItemsElementName;
}
public void SetDirectLocation(字符串名称、字符串地址、字符串城市、字符串状态)
{
//在模式中,“城市”是必需的,其他是可选的。
if(string.IsNullOrEmpty(城市))
抛出新ArgumentException();
List newItems=新列表();
List newItemsElementName=newlist();
if(name!=null)
{
newItems.Add(名称);
添加(ItemsChoiceType.Name);
}
if(地址!=null)
{
新增项目。添加(地址);
newItemsElementName.Add(ItemsChoiceType.Address);
}
newItems.Add(城市);
添加(ItemsChoiceType.City);
如果(状态!=null)
{
newItems.Add(state);
newItemsElementName.Add(ItemsChoiceType.State);
}
this.Items=newItems.ToArray();
this.ItemsElementName=newItemsElementName.ToArray();
}
}
公共静态类xmlayHelper
{
公共静态TResult GetItem(TResult[]项,TIDentifier[]项标识符,TIDentifier项标识符)
{
if(itemIdentifiers==null)
{
Assert(items==null);
返回默认值(TResult);
}
Assert(items.Length==itemIdentifiers.Length);
var i=Array.IndexOf(itemIdentifier,itemIdentifier);
if(i<0)
返回默认值(TResult);
退货项目[i];
}
}
这是我从原始答案中学到的最终解决方案。此静态类用于获取和设置适当的属性
public static class XmlPolymorphicArrayHelper
{
public static TResult GetItem<TIDentifier, TResult>(TResult[] items, TIDentifier[] itemIdentifiers, TIDentifier itemIdentifier)
{
if (itemIdentifiers == null)
{
return default(TResult);
}
var i = Array.IndexOf(itemIdentifiers, itemIdentifier);
return i < 0 ? default(TResult) : items[i];
}
public static void SetItem<TIDentifier, TResult>(ref TResult[] items, ref TIDentifier[] itemIdentifiers, TIDentifier itemIdentifier, TResult value)
{
if (itemIdentifiers == null)
{
itemIdentifiers = new[] { itemIdentifier };
items = new[] { value };
return;
}
var i = Array.IndexOf(itemIdentifiers, itemIdentifier);
if (i < 0)
{
var newItemIdentifiers = itemIdentifiers.ToList();
newItemIdentifiers.Add(itemIdentifier);
itemIdentifiers = newItemIdentifiers.ToArray();
var newItems = items.ToList();
newItems.Add(value);
items = newItems.ToArray();
}
else
{
items[i] = value;
}
}
}
这将在Items数组上设置/创建适当的成员,我可以将其用于实现此模式的多个类
public partial class LocationType
{
public string Address
{
get
{
// code here to return the correct Items[] element
}
set
{
// code here to set the correct Items[] element
}
}
}
public partial class LocationType
{
public LocationType() { }
public LocationType(string locNum)
{
SetIndirectLocation(locNum);
}
public LocationType(string name, string address, string city, string state)
{
SetDirectLocation(name, address, city, state);
}
public bool IsIndirectLocation
{
get
{
return Array.IndexOf(ItemsElementName, ItemsChoiceType.LocNum) >= 0;
}
}
public string Address { get { return (string)XmlPolymorphicArrayHelper.GetItem(Items, ItemsElementName, ItemsChoiceType.Address); } }
public string LocNum { get { return (string)XmlPolymorphicArrayHelper.GetItem(Items, ItemsElementName, ItemsChoiceType.LocNum); } }
// Other properties as desired.
public void SetIndirectLocation(string locNum)
{
if (string.IsNullOrEmpty(locNum))
throw new ArgumentException();
object[] newItems = new object[] { locNum };
ItemsChoiceType [] newItemsElementName = new ItemsChoiceType [] { ItemsChoiceType.LocNum };
this.Items = newItems;
this.ItemsElementName = newItemsElementName;
}
public void SetDirectLocation(string name, string address, string city, string state)
{
// In the schema, "City" is mandatory, others are optional.
if (string.IsNullOrEmpty(city))
throw new ArgumentException();
List<object> newItems = new List<object>();
List<ItemsChoiceType> newItemsElementName = new List<ItemsChoiceType>();
if (name != null)
{
newItems.Add(name);
newItemsElementName.Add(ItemsChoiceType.Name);
}
if (address != null)
{
newItems.Add(address);
newItemsElementName.Add(ItemsChoiceType.Address);
}
newItems.Add(city);
newItemsElementName.Add(ItemsChoiceType.City);
if (state != null)
{
newItems.Add(state);
newItemsElementName.Add(ItemsChoiceType.State);
}
this.Items = newItems.ToArray();
this.ItemsElementName = newItemsElementName.ToArray();
}
}
public static class XmlPolymorphicArrayHelper
{
public static TResult GetItem<TIDentifier, TResult>(TResult[] items, TIDentifier[] itemIdentifiers, TIDentifier itemIdentifier)
{
if (itemIdentifiers == null)
{
Debug.Assert(items == null);
return default(TResult);
}
Debug.Assert(items.Length == itemIdentifiers.Length);
var i = Array.IndexOf(itemIdentifiers, itemIdentifier);
if (i < 0)
return default(TResult);
return items[i];
}
}
public static class XmlPolymorphicArrayHelper
{
public static TResult GetItem<TIDentifier, TResult>(TResult[] items, TIDentifier[] itemIdentifiers, TIDentifier itemIdentifier)
{
if (itemIdentifiers == null)
{
return default(TResult);
}
var i = Array.IndexOf(itemIdentifiers, itemIdentifier);
return i < 0 ? default(TResult) : items[i];
}
public static void SetItem<TIDentifier, TResult>(ref TResult[] items, ref TIDentifier[] itemIdentifiers, TIDentifier itemIdentifier, TResult value)
{
if (itemIdentifiers == null)
{
itemIdentifiers = new[] { itemIdentifier };
items = new[] { value };
return;
}
var i = Array.IndexOf(itemIdentifiers, itemIdentifier);
if (i < 0)
{
var newItemIdentifiers = itemIdentifiers.ToList();
newItemIdentifiers.Add(itemIdentifier);
itemIdentifiers = newItemIdentifiers.ToArray();
var newItems = items.ToList();
newItems.Add(value);
items = newItems.ToArray();
}
else
{
items[i] = value;
}
}
}
public partial class LocationType
{
[XmlIgnore]
public string Address
{
get
{
return (string)XmlPolymorphicArrayHelper.GetItem(Items, ItemsElementName, ItemsChoiceType.Address);
}
set
{
XmlPolymorphicArrayHelper.SetItem(ref this.itemsField, ref this.itemsElementNameField, ItemsChoiceType.Address, value);
}
}
}