将 XML 导入数据集 C#
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/894451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Import XML into Dataset C#
提问by
I am trying to get a xml file into a dataset and am using the following code:
我正在尝试将 xml 文件放入数据集并使用以下代码:
DataSet ds = new DataSet("TestDataSet");
ds.ReadXml(FileName);
and this xml file:
和这个 xml 文件:
<Catalog>
<Rec>
<ITEM dt:dt="string"/>
<QTY dt:dt="string">1</QTY>
<SUB dt:dt="string">1</SUB>
<CATALOG dt:dt="string">ABC123</CATALOG>
</Rec>
<Rec>
<ITEM dt:dt="string"/>
<QTY dt:dt="string">1</QTY>
<SUB dt:dt="string">1</SUB>
<CATALOG dt:dt="string">ABC124</CATALOG>
</Rec>
<Rec>
<ITEM dt:dt="string"/>
<QTY dt:dt="string">1</QTY>
<SUB dt:dt="string">1</SUB>
<CATALOG dt:dt="string">ABC125</CATALOG>
</Rec>
</Catalog>
The trouble is that the after setting a watch on ds, it only appears to contain a table called Rec and a column called Rec_Id. If I remove the "dt:dt="String"" datatype everything works fine.
麻烦的是,在ds上设置watch后,它似乎只包含一个名为Rec的表和一个名为Rec_Id的列。如果我删除 "dt:dt="String"" 数据类型,一切正常。
I am using C#.net 2008...
我正在使用 C#.net 2008 ...
Can someone please advise of the correct way to import this data without having to alter the xml file?
有人可以建议导入此数据而无需更改xml文件的正确方法吗?
Thanks
谢谢
回答by marc_s
As soon as you define your XML namespace used in the XML elements, you can easily import this - no problem.
一旦定义了 XML 元素中使用的 XML 命名空间,就可以轻松导入它 - 没问题。
You need to have your XML look something like this:
你需要让你的 XML 看起来像这样:
<Catalog xmlns:dt="some-xml-namespace-here">
<Rec>
<ITEM dt:dt="string"/>
<QTY dt:dt="string">1</QTY>
<SUB dt:dt="string">1</SUB>
<CATALOG dt:dt="string">ABC123</CATALOG>
</Rec>
.....
</Catalog>
After I do this, your two lines of code work like a charm and the data gets imported, no problem (into 5 tables inside the DataSet).
在我这样做之后,你的两行代码就像一个魅力一样,数据被导入,没问题(到数据集中的 5 个表中)。
Marc
马克
回答by jgallant
In order for the ReadXml to function properly in this case, I think you need to specify a Schema in your XML file. Otherwise, the reader will not know what to do with the datatypes.
为了让 ReadXml 在这种情况下正常运行,我认为您需要在 XML 文件中指定一个架构。否则,读者将不知道如何处理数据类型。
回答by Richard Anthony Hein
DataSet ds = new DataSet("Whatev");
DataTable catalog = ds.Tables.Add("Catalog");
DataColumn recCol = catalog.Columns.Add("Rec");
DataTable rec = ds.Tables.Add("Rec");
rec.Columns.AddRange(new DataColumn[] {
new DataColumn("ITEM", typeof(string)),
new DataColumn("QTY", typeof(string)),
new DataColumn("SUB", typeof(string)),
new DataColumn("CATALOG", typeof(string))
});
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach (XmlNode recNode in doc.GetElementsByTagName("Rec"))
{
DataRow row = rec.Rows.Add(
recNode["ITEM"].InnerText,
recNode["QTY"].InnerText,
recNode["SUB"].InnerText,
recNode["CATALOG"].InnerText);
}
There ya go. Now there will be two tables, Catalog and Rec. I suspect you only want Rec though, because Catalog is useless. So just remove the catalog datatable code if that's the case, or add an id attribute each catalog row and link it to rec:
有你去。现在将有两个表,Catalog 和 Rec。我怀疑你只想要 Rec,因为 Catalog 没用。因此,如果是这种情况,只需删除目录数据表代码,或者为每个目录行添加一个 id 属性并将其链接到 rec:
DataSet ds = new DataSet("Whatev");
DataTable catalog = ds.Tables.Add("Catalog");
DataColumn idCol = catalog.Columns.Add("Id");
DataTable rec = ds.Tables.Add("Rec");
rec.Columns.AddRange(new DataColumn[] {
new DataColumn("ITEM", typeof(string)),
new DataColumn("QTY", typeof(string)),
new DataColumn("SUB", typeof(string)),
new DataColumn("CATALOG", typeof(string))
});
catalog.ChildRelations.Add("catToRecRelation", idCol, rec.Columns["CATALOG"]);
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
foreach (XmlNode recNode in doc.GetElementsByTagName("Rec"))
{
// Create id in parent Catalog node, based on CATALOG value
catalog.Rows.Add(recNode["CATALOG"].InnerText);
DataRow row = rec.Rows.Add(
recNode["ITEM"].InnerText,
recNode["QTY"].InnerText,
recNode["SUB"].InnerText,
recNode["CATALOG"].InnerText);
}
var childRows = catalog.Rows[0].GetChildRows("catToRecRelation");
回答by Birkto
I use this code...
我用这个代码...
To generate the XML:
要生成 XML:
// you need to create a datatable, from a sql query, linq, your choice...
DataTable _dt = new DataTable();
// write the datatable with schema
dt.WriteXml("datatable.xml", XmlWriteMode.WriteSchema);
To read the XML:
要读取 XML:
DataTable dt = new DataTable ();
dt.Clear();
dt.ReadXml("datatable.xml", XmlReadMode.ReadSchema);
The result datatable can be complemented with these functions, this way you can convert it to IList, you need to create an object with the same pattern of columns, it's really more practical this way:
结果数据表可以用这些函数来补充,这样你就可以把它转换为IList,你需要创建一个具有相同列模式的对象,这种方式确实更实用:
public IList<T> toList<T>(DataTable table)
{
List<T> list = new List<T>();
T item;
Type listItemType = typeof(T);
for (int i = 0; i < table.Rows.Count; i++)
{
item = (T)Activator.CreateInstance(listItemType);
mapRow(item, table.Rows[i], listItemType);
list.Add(item);
}
return list;
}
private void mapRow(object vOb, System.Data.DataRow dr, Type type)
{
try
{
for (int col = 0; col < dr.Table.Columns.Count; col++)
{
var columnName = dr.Table.Columns[col].ColumnName;
var prop = type.GetProperty(columnName.ToUpper());
object data = dr[col];
prop.SetValue(vOb, data, null);
}
}
catch (Exception ex)
{
throw ex;
}
}
Actually, I'm working on an app that use XML generated from SQL tables. Basically, use the functions above, I create other small app (to support the first one) that scan the package of XML (XML per table) and create the layers business, access, object and a flow control for proper writing & reading of the XML.
实际上,我正在开发一个使用从 SQL 表生成的 XML 的应用程序。基本上,使用上面的功能,我创建了其他小应用程序(以支持第一个),扫描 XML 包(每个表的 XML)并创建层业务、访问、对象和流控制以正确写入和读取XML。
回答by Richard Anthony Hein
This will make it parseable. The dt namespace usually refers to xmlns:dt="urn:schemas-microsoft-com:datatypes". Something or someone messed up your XML, but if you must be able to import it, you can just modify the xmlns attributes on the catalog element as shown:
这将使其可解析。dt 命名空间通常是指 xmlns:dt="urn:schemas-microsoft-com:datatypes"。某些东西或某人弄乱了您的 XML,但如果您必须能够导入它,您只需修改目录元素上的 xmlns 属性,如下所示:
string xml = @"<Catalog xmlns=""dt"" xmlns:dt=""dt"">
<Rec>
<ITEM dt:dt=""string""/>
<QTY dt:dt=""string"">1</QTY>
<SUB dt:dt=""string"">1</SUB>
<CATALOG dt:dt=""string"">ABC123</CATALOG>
</Rec>
<Rec>
<ITEM dt:dt=""string""/>
<QTY dt:dt=""string"">1</QTY>
<SUB dt:dt=""string"">1</SUB>
<CATALOG dt:dt=""string"">ABC124</CATALOG>
</Rec>
<Rec>
<ITEM dt:dt=""string""/>
<QTY dt:dt=""string"">1</QTY>
<SUB dt:dt=""string"">1</SUB>
<CATALOG dt:dt=""string"">ABC125</CATALOG>
</Rec>
</Catalog>";
DataSet ds = new DataSet("Whatev");
TextReader txtReader = new StringReader(xml);
XmlReader reader = new XmlTextReader(txtReader);
ds.ReadXml(reader);
Debug.Assert(ds.Tables.Count ==5);
Debug.Assert((string)ds.Tables[2].Rows[0][0] == "string");
Debug.Assert((string)ds.Tables[3].Rows[0][1] == "1");
Also Marc is correct, but with the definition above you can generate a matching schema:
Marc 也是正确的,但根据上面的定义,您可以生成匹配的模式:
<xs:schema xmlns:dt="dt" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="dt" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="Catalog"><xs:complexType> <xs:sequence><xs:element maxOccurs="unbounded" name="Rec"><xs:complexType><xs:sequence><xs:element name="ITEM"><xs:complexType><xs:attribute ref="dt:dt" use="required" /></xs:complexType></xs:element><xs:element name="QTY"><xs:complexType>
<xs:simpleContent><xs:extension base="xs:unsignedByte"><xs:attribute ref="dt:dt" use="required" /></xs:extension></xs:simpleContent></xs:complexType>
</xs:element><xs:element name="SUB"><xs:complexType><xs:simpleContent><xs:extension base="xs:unsignedByte"><xs:attribute ref="dt:dt" use="required" /></xs:extension></xs:simpleContent></xs:complexType></xs:element><xs:element name="CATALOG"><xs:complexType><xs:simpleContent><xs:extension base="xs:string"><xs:attribute ref="dt:dt" use="required" /></xs:extension></xs:simpleContent></xs:complexType></xs:element></xs:sequence></xs:complexType></xs:element></xs:sequence></xs:complexType></xs:element><xs:attribute name="dt" type="xs:string" /></xs:schema>
The attribute "dt" is a reference attribute. So the xml cannot be valid against any schema without the xmlns="ds" declaration as well.
属性“dt”是参考属性。因此,如果没有 xmlns="ds" 声明,xml 也不能对任何模式有效。

