如何在C#中提取XML的CDATA段数据并准备导入数据库?
C#提取XML中CDATA段内的XML数据并导入数据库
核心思路
- 读取外层XML文档,遍历每个
<Doc>节点下的<Content>节点 - 提取
<Content>节点的文本内容(即CDATA段内的XML字符串) - 将提取到的XML字符串解析为新的XML文档
- 从解析后的XML中提取所需数据,执行数据库插入操作
代码实现示例
1. 使用XDocument(LINQ to XML)处理XML
using System; using System.Xml.Linq; using System.Data.SqlClient; class XmlCDataProcessor { static void Main(string[] args) { string xmlFilePath = "path/to/your/xml/file.xml"; string connectionString = "Your_Database_Connection_String"; // 加载外层XML XDocument outerXml = XDocument.Load(xmlFilePath); // 遍历每个外层Doc节点 foreach (XElement docElement in outerXml.Descendants("Doc")) { // 获取Content节点的CDATA内容,去除首尾空白 string cdataContent = docElement.Element("Content")?.Value?.Trim(); if (string.IsNullOrWhiteSpace(cdataContent)) continue; try { // 解析CDATA内的XML字符串 XDocument innerXml = XDocument.Parse(cdataContent); // 提取Header数据 XElement header = innerXml.Element("Doc")?.Element("Header"); if (header != null) { string docNumber = header.Attribute("DocNumber")?.Value; string description = header.Attribute("Description")?.Value; // 插入Header到数据库 InsertHeaderToDatabase(docNumber, description, connectionString); } // 提取Pos数据 foreach (XElement posElement in innerXml.Descendants("Pos")) { string posId = posElement.Attribute("Id")?.Value; string posName = posElement.Attribute("Name")?.Value; string docNumber = innerXml.Element("Doc")?.Element("Header")?.Attribute("DocNumber")?.Value; // 插入Pos到数据库 InsertPosToDatabase(posId, posName, docNumber, connectionString); } } catch (Exception ex) { Console.WriteLine($"处理CDATA内容失败: {ex.Message}"); continue; } } } static void InsertHeaderToDatabase(string docNumber, string description, string connectionString) { string sql = "INSERT INTO Headers (DocNumber, Description) VALUES (@DocNumber, @Description)"; using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@DocNumber", docNumber); cmd.Parameters.AddWithValue("@Description", description); cmd.ExecuteNonQuery(); } } } static void InsertPosToDatabase(string posId, string posName, string docNumber, string connectionString) { string sql = "INSERT INTO Positions (PosId, PosName, DocNumber) VALUES (@PosId, @PosName, @DocNumber)"; using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@PosId", posId); cmd.Parameters.AddWithValue("@PosName", posName); cmd.Parameters.AddWithValue("@DocNumber", docNumber); cmd.ExecuteNonQuery(); } } } }
2. 使用XmlDocument(传统XML处理)
如果习惯使用XmlDocument,也可以用以下方式:
using System; using System.Xml; using System.Data.SqlClient; class XmlCDataProcessor { static void Main(string[] args) { string xmlFilePath = "path/to/your/xml/file.xml"; string connectionString = "Your_Database_Connection_String"; XmlDocument outerDoc = new XmlDocument(); outerDoc.Load(xmlFilePath); XmlNodeList docNodes = outerDoc.SelectNodes("//Doc"); foreach (XmlNode docNode in docNodes) { XmlNode contentNode = docNode.SelectSingleNode("Content"); if (contentNode == null) continue; string cdataText = contentNode.InnerText.Trim(); if (string.IsNullOrWhiteSpace(cdataText)) continue; try { XmlDocument innerDoc = new XmlDocument(); innerDoc.LoadXml(cdataText); XmlNode headerNode = innerDoc.SelectSingleNode("//Header"); if (headerNode != null) { string docNumber = headerNode.Attributes["DocNumber"]?.Value; string description = headerNode.Attributes["Description"]?.Value; InsertHeaderToDatabase(docNumber, description, connectionString); } XmlNodeList posNodes = innerDoc.SelectNodes("//Pos"); foreach (XmlNode posNode in posNodes) { string posId = posNode.Attributes["Id"]?.Value; string posName = posNode.Attributes["Name"]?.Value; string docNumber = innerDoc.SelectSingleNode("//Header")?.Attributes["DocNumber"]?.Value; InsertPosToDatabase(posId, posName, docNumber, connectionString); } } catch (Exception ex) { Console.WriteLine($"处理CDATA内容失败: {ex.Message}"); continue; } } } // 数据库插入方法同上面的示例 static void InsertHeaderToDatabase(string docNumber, string description, string connectionString) { string sql = "INSERT INTO Headers (DocNumber, Description) VALUES (@DocNumber, @Description)"; using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@DocNumber", docNumber); cmd.Parameters.AddWithValue("@Description", description); cmd.ExecuteNonQuery(); } } } static void InsertPosToDatabase(string posId, string posName, string docNumber, string connectionString) { string sql = "INSERT INTO Positions (PosId, PosName, DocNumber) VALUES (@PosId, @PosName, @DocNumber)"; using (SqlConnection conn = new SqlConnection(connectionString)) { conn.Open(); using (SqlCommand cmd = new SqlCommand(sql, conn)) { cmd.Parameters.AddWithValue("@PosId", posId); cmd.Parameters.AddWithValue("@PosName", posName); cmd.Parameters.AddWithValue("@DocNumber", docNumber); cmd.ExecuteNonQuery(); } } } }
注意事项
- 命名空间处理:如果内层XML包含命名空间,需要使用
XNamespace(LINQ to XML)或XmlNamespaceManager(XmlDocument)来定位元素,避免找不到节点的问题。 - 异常处理:添加try-catch块捕获XML解析、数据库操作中的异常,避免单个数据项处理失败导致整个程序终止。
- 性能优化:若XML文件体积较大,建议使用
XmlReader流式处理,减少内存占用。 - 事务处理:如果需要保证Header和Pos数据的一致性,可使用数据库事务包裹同一文档的插入操作。
内容的提问来源于stack exchange,提问作者jeffers
相关产品推荐
相关产品推荐

