我需要在C#中解析XML响应并在SQL中加载。 简单来说,我知道如何使用XMLSerializer来解析xml,所以这不是我想要的。我关心的是我从Web请求中收到的XML结构。下面是我从xml
收到的xml的子集<apiXML>
<recordList>
<record id="31" >
<administration_name>admin1</administration_name>
<creator>Leekha, Mohit</creator>
<object_category>painting</object_category>
<object_number>1243</object_number>
<id>31</id>
<reproduction.reference>2458.jpg</reproduction.reference>
<title lang="nl-NL" invariant="false">The Title1</title>
<title lang="nl-NL" invariant="false">The Title</title>
<title lang="nl-NL" invariant="false">Different Title</title>
</record>
<record id="32" >
<administration_name>admin1</administration_name>
<creator>Leekha, Mohit</creator>
<object_category>painting</object_category>
<object_number>AL1111</object_number>
<id>32</id>
<reproduction.reference>AL1111.jpg</reproduction.reference>
<title lang="nl-NL" invariant="false">Health</title>
</record>
<record id="34" >
<administration_name>admin2</administration_name>
<creator>Leekha,Mohit</creator>
<creator>System</creator>
<object_category>earthenware</object_category>
<object_category>ABC</object_category>
<object_category>Remote</object_category>
<object_number>Z.567 & X-124</object_number>
<id>34</id>
<reproduction.reference>Z.567 & X-124(1).jpg</reproduction.reference>
<reproduction.reference>Z.567 & X-124(2).jpg</reproduction.reference>
<reproduction.reference>Z.567 & X-124(3).jpg</reproduction.reference>
</record>
</recordList>
</apiXML>
我的担忧:
所以我要求的是建议我如何处理方案。欢迎任何建议
答案 0 :(得分:0)
您需要一些支持类来按顺序对XML进行反序列化,因为您没有指定任何其他要求。
您的数据库将为您的记录元素和其中的所有集合提供表格。
这些类将保存XML的内存表示形式。根目录是Api
类。
[XmlRoot("apiXML")]
public class Api
{
[XmlArray("recordList")]
[XmlArrayItem("record", typeof(Record))]
public List<Record> RecordList {get;set;}
}
[Serializable]
public class Record
{
[XmlAttribute("id")]
public int RecordId {get;set;}
[XmlElement("id")]
public int Id {get;set;}
[XmlElement("administration_name")]
public string AdministrationName {get;set;}
[XmlElement("object_number")]
public string ObjectNumber {get;set;}
[XmlElement("creator")]
public List<Creator> Creators {get;set;}
[XmlElement("object_category")]
public List<ObjectCategory> ObjectCategories {get;set;}
[XmlElement("reproduction.reference")]
public List<ReproductionReference> ReproductionReferences {get;set;}
[XmlElement("title")]
public List<Title> Titles {get;set;}
}
[Serializable]
public class Title:Child
{
[XmlAttribute("invariant")]
public bool Invariant {get;set;}
[XmlAttribute("lang")]
public string Culture {get;set;}
[XmlText]
public string Text {get;set;}
}
public class Child
{
[XmlIgnore]
public int ParentId {get;set;}
}
[Serializable]
public class Creator:Child
{
[XmlText]
public string Text {get;set;}
}
[Serializable]
public class ObjectCategory:Child
{
[XmlText]
public string Text {get;set;}
}
[Serializable]
public class ReproductionReference:Child
{
[XmlText]
public string Text {get;set;}
}
正确注释类后反序列化XML只需要一对 行:
var ser = new XmlSerializer(typeof(Api));
var sr = new StringReader(xml);
var api = (Api) ser.Deserialize(sr);
在变量api
中,我们现在拥有了可以在关系数据库模式上投影的内存中对象图。对于标准化模型,您需要以下表格:
在这些表之间,您需要遵循所有相同约定的链接表,例如Record和Creator之间的约定:
我假设您知道如何创建这些表并创建与数据库的连接。
// use an SqlAdapter.Fill to get the below dataset call
// sqlAdapter.Fill(ds);
var ds = new DataSet();
// this is here so you can test without a database
// test mocking code
var recTable = ds.Tables.Add("Record");
recTable.Columns.Add("Id");
recTable.Columns.Add("AdministrationName");
recTable.Columns.Add("ObjectNumber");
var creTable = ds.Tables.Add("Creator");
creTable.Columns.Add("Id", typeof(int)).AutoIncrement = true;
creTable.Columns.Add("Text");
var reccreTable = ds.Tables.Add("RecordCreator");
reccreTable.Columns.Add("RecordId");
reccreTable.Columns.Add("CreatorId");
// end mocking code
// copy object graph and build link tables
foreach(var record in api.RecordList)
{
// each main record is created
var rtRow = recTable.NewRow();
rtRow["Id"] = record.Id;
rtRow["AdministrationName"] = record.AdministrationName;
rtRow["ObjectNumber"] = record.ObjectNumber;
recTable.Rows.Add(rtRow);
// handle each collection
foreach(var creator in record.Creators)
{
DataRow creRow; // will hold our Creator row
// first try to find if the Text is already there
var foundRows = creTable.Select(String.Format("Text='{0}'", creator.Text));
if (foundRows.Length < 1)
{
// if not, add it to the Creator table
creRow = creTable.NewRow(); // Id is autoincrement!
creRow["Text"] = creator.Text;
creTable.Rows.Add(creRow);
}
else
{
// otherwise, we found an existing one
creRow = foundRows[0];
}
// link record and creator
var reccreRow = reccreTable.NewRow();
reccreRow["RecordId"] = record.Id;
reccreRow["CreatorId"] = creRow["Id"];
reccreTable.Rows.Add(reccreRow);
}
// the other collections follow a similar pattern but is left for the reader
}
// now call Update to write the changes to the db.
// SqlDataAdapter.Update(ds);
结束了将SQL存储在RDBMS数据库中而不会丢失信息所需的代码和结构。