DataSet生成XML时移除Items表OrderNumber列的解决办法
问题分析与解决方案
这个问题我碰到过不少次——因为你已经在DataSet里建立了DataRelation关联,关联字段是没法直接删除的,不过我们可以换个思路:在生成XML之后再移除不需要的节点,这里有几个适配不同.NET版本的可行方案:
先明确你的场景
你通过以下代码生成嵌套XML,但需要移除Items节点下的OrderNumber列:
DataSet ds = new DataSet("OrderDetail"); DataTable Detail = new DataTable("Detail"); DataTable Items = new DataTable("Items"); string query = "Some Query"; SqlDataAdapter dataAdapt = new SqlDataAdapter(query , conn); dataAdapt.Fill(Detail); ds.Tables.Add(Detail); string loopingquery = "Some Query"; SqlDataAdapter dataAdapt1 = new SqlDataAdapter(loopingquery, conn); dataAdapt1.Fill(Items); ds.Tables.Add(Items); DataRelation relation = ds.Relations.Add("relation", ds.Tables["Detail"].Columns["OrderNumber"], ds.Tables["Items"].Columns["OrderNumber"]); relation.Nested = true; ds.WriteXml(Server.MapPath("~/" + Detail.Rows[0]["OrderNumber"] + "_XML.xml"));
当前生成的XML(需移除Items下的OrderNumber节点):
<OrderDetail> <Detail> <OrderNumber>354699</OrderNumber> <OrderDate>01/09/2018</OrderDate> <Items> <OrderNumber>354699</OrderNumber> <!-- 需要移除 --> <Quantity>1</Quantity> <Sku>test240</Sku> <Item>testEye®</Item> <Price>22.95</Price> </Items> <Items> <OrderNumber>354699</OrderNumber> <!-- 需要移除 --> <Quantity>1</Quantity> <Sku /> <Item>test</Item> <Price>-32.95</Price> </Items> </Detail> </OrderDetail>
方案1:使用LINQ to XML(适用于.NET 3.5及以上版本)
这种方式代码简洁高效,先把DataSet转为XML字符串,再用LINQ精准移除指定节点:
using System.Xml.Linq; // 必须引入命名空间 string xml = ds.GetXml(); XDocument doc = XDocument.Parse(xml); // 只移除Items节点下的OrderNumber,不会影响Detail里的 doc.Descendants("OrderNumber") .Where(node => node.Parent.Name == "Items") .Remove(); doc.Save(Server.MapPath("~/" + Detail.Rows[0]["OrderNumber"] + "_XML.xml"));
方案2:使用XmlDocument(适用于所有.NET版本,包括2.0)
兼容性最强的方案,适合老项目:
using System.Xml; // 必须引入命名空间 string xmlStr = ds.GetXml(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlStr); // 遍历所有Items节点 XmlNodeList itemsNodes = xmlDoc.GetElementsByTagName("Items"); foreach (XmlNode itemNode in itemsNodes) { // 找到当前Items下的OrderNumber节点(注意不要用//,避免匹配全局节点) XmlNode orderNumNode = itemNode.SelectSingleNode("OrderNumber"); if (orderNumNode != null) // 加空值判断避免运行时异常 { itemNode.RemoveChild(orderNumNode); } } xmlDoc.Save(Server.MapPath("~/" + Detail.Rows[0]["OrderNumber"] + "_XML.xml"));
方案3:先写XML文件再修改(适用于所有.NET版本,大XML场景更友好)
如果生成的XML体积较大,直接操作文件可以节省内存:
using System.Xml; // 必须引入命名空间 string filePath = Server.MapPath("~/" + Detail.Rows[0]["OrderNumber"] + "_XML.xml"); // 先写出原始XML ds.WriteXml(filePath); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(filePath); // 移除指定节点 XmlNodeList itemsNodes = xmlDoc.SelectNodes("//Items"); foreach (XmlNode itemNode in itemsNodes) { XmlNode orderNumNode = itemNode.SelectSingleNode("OrderNumber"); if (orderNumNode != null) { itemNode.RemoveChild(orderNumNode); } } xmlDoc.Save(filePath);
内容的提问来源于stack exchange,提问作者Mitesh Jain
相关产品推荐
相关产品推荐

