如何使用XPath按指定参数筛选XML节点后完成实体类反序列化
实现方案
完全可以实现,以下是两种常用的落地方案:
方案1:全量反序列化后筛选(推荐,逻辑简单兼容性高)
适合XML文件体积不大的场景,直接复用你已有的反序列化逻辑,筛选操作在反序列化后的对象上完成即可:
// 你原有正常运行的反序列化逻辑 AddressInfo deserialized; XmlSerializer deserializer = new XmlSerializer(typeof(AddressInfo)); using (TextReader reader = new StreamReader(@"D:\dataAPIv2\dataAPI\Files\sample_data.xml")) { object obj = deserializer.Deserialize(reader); deserialized = (AddressInfo)obj; } // 按城市代码筛选,只保留符合条件的City数据 int targetCityCode = 1101; // 替换为你的目标城市代码参数 deserialized.City = deserialized.City.Where(c => c.city_code == targetCityCode).ToList();
方案2:XPath筛选后反序列化(适合大体积XML场景)
如果XML文件体积很大,全量反序列化内存占用过高,可以用该方案,先筛选出符合条件的City节点,包装为合法的XML结构后再反序列化:
XmlDocument doc = new XmlDocument(); doc.Load(System.Web.HttpContext.Current.Server.MapPath("~/Files/sample_data.xml")); XmlNodeList matchedCityNodes = doc.SelectNodes($"/AddressInfo/City[@code='{citycode}']"); // 构造仅包含匹配城市的AddressInfo XML片段 XmlDocument filteredDoc = new XmlDocument(); XmlElement rootNode = filteredDoc.CreateElement("AddressInfo"); filteredDoc.AppendChild(rootNode); foreach (XmlNode cityNode in matchedCityNodes) { // 导入筛选到的City节点到新XML文档 XmlNode importedNode = filteredDoc.ImportNode(cityNode, true); rootNode.AppendChild(importedNode); } // 反序列化筛选后的XML AddressInfo filteredResult; XmlSerializer deserializer = new XmlSerializer(typeof(AddressInfo)); using (XmlReader reader = new XmlNodeReader(filteredDoc)) { filteredResult = (AddressInfo)deserializer.Deserialize(reader); }
注意事项
- 你当前City类中定义的
public AddressInfo AddressInfo { get; set; }属性若无实际业务用途,建议删除,避免序列化/反序列化时出现非预期的节点匹配问题。 - 若城市代码
citycode为用户传入的参数,不建议直接拼接XPath字符串,可改用XPathNavigator带参数查询的方式避免XXE注入风险。
内容的提问来源于stack exchange,提问作者incbeatz
相关产品推荐
相关产品推荐

