DataTable到Xdocument自定义
本文关键字:自定义 Xdocument DataTable | 更新日期: 2023-09-27 18:24:54
我有一个数据表,看起来像下面的
type cname ctable text allowgroupping
StringFilter AAA Table1 Good,Bad Yes
StringFilter BBB Table2 Ugly No
StringFilter CCC Table3 Lucky Yes
从该表中,我想生成以下XML
<Filters Date ="25.07.2012 22:50">
<StringFilter cname="AAA" ctable="Table1" allowgroupping="Yes">Good,Bad</StringFilter>
<StringFilter cname="BBB" ctable="Table2" allowgroupping="No">Ugly</StringFilter >
<StringFilter cname="CCC" ctable="Table3" allowgroupping="Yes">Lucky</StringFilter >
</Filters>
- type列表示标记
- cname和able以及allowgroupping是属性
- 列文本表示内部文本
你能帮我用linq和xDocument实现这个吗?
添加对System.Data.DataSetExtensions
的引用
using System.Data.DataSetExtensions;
var XDocument doc = new XDocument();
var root = new XElement("Filters");
var items = dt.Rows.AsIEnumberable().Select(row=> new XElement("StringFilter", new XAttribute("cname",(string) row["cname"]),
/*additional attributes here*/
(string) row["text"] ));
root.Add(items);
doc.Add(root);
@CamBruce给出了正确答案System.Data.DataSetExtensions
是不必要的
如果使用AsEnumerable
而不是AsIEnumberable
以下是子元素的工作示例:
//Build DataTable for the purposes of this Example:
DataTable dt = new DataTable();
//Add Columns:
dt.Columns.Add("WidgetType");//The default Type is "string".
dt.Columns.Add("WidgetID", typeof(int));
dt.Columns.Add("WidgetName");
dt.Columns.Add("WidgetPrice", typeof(decimal));
dt.Columns.Add("SubWidget");
//Add Rows:
dt.Rows.Add("Watch", 1, "Dial", .50, "Gear");
dt.Rows.Add("Tablet", 2, "Screen", 14.99, null);
dt.Rows.Add("Watch", 3, "Strap", 1, "Buckle");
//Prep XML Objects:
XDocument xDoc = new XDocument();
//xDoc.Declaration = new XDeclaration("1.0", "utf-16", null);//Optional: SQL-Server already stores XML using UTF-16. The default for XDocument is also UTF-16 when the Declaration is null. - 07/26/2018 - MCR.
XElement xRoot = new XElement("Root");
xRoot.SetAttributeValue("Date", string.Format("{0:MM/dd/yyyy hh:mm tt}", DateTime.Now));//Optional: Add Attribute to Root.
//Populate XML from DataTable:
xRoot.Add(dt.AsEnumerable()
//.Where(r => r.Field<string>("WidgetType") == "Watch")//Optional: Add Filter. This works.
.Select(r => new XElement(r.Field<string>("WidgetType"),//Add Row Element
//r.Field<decimal>("WidgetPrice"),//Optional: Populate Element Value.
new XAttribute("WidgetID", r.Field<int>("WidgetID")),//Optional: Add Attribute.
new XAttribute("WidgetName", r.Field<string>("WidgetName")),//Optional: Add Attribute.
new XElement("SubWidget", r.Field<string>("SubWidget"))//Optional: Add Child-Element.
)
)
);
//Finish assembling the XML:
xDoc.Add(xRoot);
//View the XML Data:
string sDoc = xDoc.ToString();//View Indented-XML as a string.
//View the XML as it would appear in a Standalone File:
System.IO.StringWriter sw = new System.IO.StringWriter();
xDoc.Save(sw);
string sWrite = sw.ToString();//This adds the XML Declaration to the string output.
sDoc字符串:
<Root Date="07/26/2018 04:07 AM">
<Watch WidgetID="1" WidgetName="Dial">
<SubWidget>Gear</SubWidget>
</Watch>
<Tablet WidgetID="2" WidgetName="Screen">
<SubWidget />
</Tablet>
<Watch WidgetID="3" WidgetName="Strap">
<SubWidget>Buckle</SubWidget>
</Watch>
</Root>
sWrite字符串:
<?xml version="1.0" encoding="utf-16"?>
<Root Date="07/26/2018 04:07 AM">
<Watch WidgetID="1" WidgetName="Dial">
<SubWidget>Gear</SubWidget>
</Watch>
<Tablet WidgetID="2" WidgetName="Screen">
<SubWidget />
</Tablet>
<Watch WidgetID="3" WidgetName="Strap">
<SubWidget>Buckle</SubWidget>
</Watch>
</Root>
使用此选项将XDocument
作为Xml
参数值传递给SQL Server Sproc:
cmd.Parameters.Add("@WidgetXml", SqlDbType.Xml).Value
= new System.Data.SqlTypes.SqlXml(xDoc.CreateReader());
如果写入文件,我会使用xDoc.Save(FileName)
如果要准确预览XML在文件中的显示方式,请使用StringWriter
如果您希望在调试/故障排除时获得数据元素的基本/简单视图,
然后您可以在遍历代码时使用xDoc.ToString()
,但请注意,它可能缺少一些东西,如Declaration
我不是XML专家,但我认为StringWriter
和xDoc.Save(FileName)
应该将额外/必要的信息添加到XML输出中(甚至超出XML声明,这取决于您在XML变量中设置的属性)
也许有人可以在评论中权衡一下他们过去的经历。