查找重复的 XML 节点并最小化 XML 结构和大小
Posted
技术标签:
【中文标题】查找重复的 XML 节点并最小化 XML 结构和大小【英文标题】:Finding duplicate XML nodes and minimize XML strcutre and size 【发布时间】:2013-10-06 12:40:50 【问题描述】:我有当前的 XML,其中包含许多重复项。
<XML version="1.0">
<body>
<optionTree>
<device modelDescription="20 Slot MX2000 Chassis, Base with 1 RE, SFBs, Fan Trays, AC Power" ProductId="1542671" modelCatalogNum="MX2020-BASE-AC" price="450000" quantity="1" userRemovable="1">
<optionItem modelDescription="MPC Slot 0" slotIndex="1" isSingleSelected="1">
<device modelDescription="2xTrio Chipset Enhanced MPC, 1588v2, port queuing, price includes full scale L2/L2.5 and reduced scale L3 features" ProductId="1540947" modelCatalogNum="MX-MPC2E-3D-P" price="70000">
<optionItem modelDescription="MIC Slot 1" slotIndex="1" isSingleSelected="1">
<device modelDescription="20x10/100/1000 MIC for MX, requires optics sold separately" ProductId="334748" modelCatalogNum="MIC-3D-20GE-SFP" price="9000">
<optionItem modelDescription="SFP Slot 1" slotIndex="1" isSingleSelected="1">
<device modelDescription="SFP capable of support 10/100/1000 speeds" ProductId="291564" modelCatalogNum="SFP-1GE-FE-E-T" price="395" />
<device modelDescription="Small Form Factor Pluggable supporting 1000BASE-EX Gigabit Ethernet Optic Module, 40km." ProductId="205359" modelCatalogNum="SFP-GE40KM" price="2500" />
<device modelDescription="Small Form Factor Pluggable 1000Base-SX Gigabit Ethernet Optic Module" ProductId="51804" modelCatalogNum="SFP-1GE-SX" price="500" />
<device modelDescription="Small Form Factor Pluggable 1000Base-T Gigabit Ethernet Module (uses Cat 5 cable)" ProductId="51805" modelCatalogNum="SFP-1GE-T" price="395" />
<device modelDescription="Small Form Factor Pluggable 1000Base-LH Gigabit Ethernet Optic Module" ProductId="205257" modelCatalogNum="SFP-1GE-LH" price="5995" />
<device modelDescription="Small Form Factor Pluggable 1000Base-LX Gigabit Ethernet Optic Module" ProductId="51803" modelCatalogNum="SFP-1GE-LX" price="995" />
</optionItem>
<optionItem modelDescription="SFP Slot 2" slotIndex="2" isSingleSelected="1">
<device modelDescription="SFP capable of support 10/100/1000 speeds" ProductId="291564" modelCatalogNum="SFP-1GE-FE-E-T" price="395" />
<device modelDescription="Small Form Factor Pluggable supporting 1000BASE-EX Gigabit Ethernet Optic Module, 40km." ProductId="205359" modelCatalogNum="SFP-GE40KM" price="2500" />
<device modelDescription="Small Form Factor Pluggable 1000Base-SX Gigabit Ethernet Optic Module" ProductId="51804" modelCatalogNum="SFP-1GE-SX" price="500" />
<device modelDescription="Small Form Factor Pluggable 1000Base-T Gigabit Ethernet Module (uses Cat 5 cable)" ProductId="51805" modelCatalogNum="SFP-1GE-T" price="395" />
<device modelDescription="Small Form Factor Pluggable 1000Base-LH Gigabit Ethernet Optic Module" ProductId="205257" modelCatalogNum="SFP-1GE-LH" price="5995" />
<device modelDescription="Small Form Factor Pluggable 1000Base-LX Gigabit Ethernet Optic Module" ProductId="51803" modelCatalogNum="SFP-1GE-LX" price="995" />
</optionItem>
<optionItem modelDescription="SFP Slot 3" slotIndex="3" isSingleSelected="1">
<device modelDescription="SFP capable of support 10/100/1000 speeds" ProductId="291564" modelCatalogNum="SFP-1GE-FE-E-T" price="395" />
<device modelDescription="Small Form Factor Pluggable supporting 1000BASE-EX Gigabit Ethernet Optic Module, 40km." ProductId="205359" modelCatalogNum="SFP-GE40KM" price="2500" />
<device modelDescription="Small Form Factor Pluggable 1000Base-SX Gigabit Ethernet Optic Module" ProductId="51804" modelCatalogNum="SFP-1GE-SX" price="500" />
<device modelDescription="Small Form Factor Pluggable 1000Base-T Gigabit Ethernet Module (uses Cat 5 cable)" ProductId="51805" modelCatalogNum="SFP-1GE-T" price="395" />
<device modelDescription="Small Form Factor Pluggable 1000Base-LH Gigabit Ethernet Optic Module" ProductId="205257" modelCatalogNum="SFP-1GE-LH" price="5995" />
<device modelDescription="Small Form Factor Pluggable 1000Base-LX Gigabit Ethernet Optic Module" ProductId="51803" modelCatalogNum="SFP-1GE-LX" price="995" />
</optionItem>
</device>
</optionItem>
</device>
</optionItem>
</device>
</optionTree>
</body>
</XML>
我想最小化这个 XML 并删除所有重复的 XML 节点。
我想创建一个执行以下操作的代码:
遍历此 XML 并找到重复的“设备”元素。 对于每个重复节点,删除其所有属性,“ProductId”属性除外。 在底部创建一个图例如下: 将创建一个名为“Devices”的新元素,其中包含所有已删除 XML 节点的完整详细信息。最终的 XML 应该如下所示:
<XML version="1.0">
<body>
<optionTree>
<device modelDescription="20 Slot MX2000 Chassis, Base with 1 RE, SFBs, Fan Trays, AC Power" ProductId="1542671" modelCatalogNum="MX2020-BASE-AC" price="450000" quantity="1" userRemovable="1">
<optionItem modelDescription="MPC Slot 0" slotIndex="1" isSingleSelected="1">
<device modelDescription="2xTrio Chipset Enhanced MPC, 1588v2, port queuing, price includes full scale L2/L2.5 and reduced scale L3 features" ProductId="1540947" modelCatalogNum="MX-MPC2E-3D-P" price="70000">
<optionItem modelDescription="MIC Slot 1" slotIndex="1" isSingleSelected="1">
<device modelDescription="20x10/100/1000 MIC for MX, requires optics sold separately" ProductId="334748" modelCatalogNum="MIC-3D-20GE-SFP" price="9000">
<optionItem modelDescription="SFP Slot 1" slotIndex="1" isSingleSelected="1">
<device ProductId="291564" />
<device ProductId="205359" />
<device ProductId="51804" />
<device ProductId="51805" />
<device ProductId="205257" />
<device ProductId="51803" />
</optionItem>
<optionItem modelDescription="SFP Slot 2" slotIndex="2" isSingleSelected="1">
<device ProductId="291564" />
<device ProductId="205359" />
<device ProductId="51804" />
<device ProductId="51805" />
<device ProductId="205257" />
<device ProductId="51803" />
</optionItem>
<optionItem modelDescription="SFP Slot 3" slotIndex="3" isSingleSelected="1">
<device ProductId="291564" />
<device ProductId="205359" />
<device ProductId="51804" />
<device ProductId="51805" />
<device ProductId="205257" />
<device ProductId="51803" />
</optionItem>
</device>
</optionItem>
</device>
</optionItem>
</device>
</optionTree>
<devices>
<device ProductId="291564" modelDescription="SFP capable of support 10/100/1000 speeds" modelCatalogNum="SFP-1GE-FE-E-T" price="395" />
<device ProductId="205359" modelDescription="Small Form Factor Pluggable supporting 1000BASE-EX Gigabit Ethernet Optic Module, 40km." modelCatalogNum="SFP-GE40KM" price="2500" />
<device ProductId="51804" modelDescription="Small Form Factor Pluggable 1000Base-SX Gigabit Ethernet Optic Module" modelCatalogNum="SFP-1GE-SX" price="500" />
<device ProductId="51805" modelDescription="Small Form Factor Pluggable 1000Base-T Gigabit Ethernet Module (uses Cat 5 cable)" modelCatalogNum="SFP-1GE-T" price="395" />
<device ProductId="205257" modelDescription="Small Form Factor Pluggable 1000Base-LH Gigabit Ethernet Optic Module" modelCatalogNum="SFP-1GE-LH" price="5995" />
<device ProductId="51803" modelDescription="Small Form Factor Pluggable 1000Base-LX Gigabit Ethernet Optic Module" modelCatalogNum="SFP-1GE-LX" price="995" />
</devices>
</body>
</XML>
我已经找到了一个查找重复 XML 节点的代码,但是我想做的不仅仅是找到上面描述的那些重复项。
【问题讨论】:
【参考方案1】:应该可以解决您的问题的快速而肮脏的解决方案:
//find duplicates
var duplicates = doc.Descendants("device")
.GroupBy(n => n.ToString())
.Where(g => g.Count() > 1)
.ToArray();
//remove attributes on all duplicates
foreach (var attribute in duplicates.SelectMany(g => g)
.SelectMany(el => el.Attributes()
.Where(attribute => attribute.Name != "ProductId"))
.ToArray())
attribute.Remove();
//add new element
doc.Descendants("body")
.Single()
.Add(new XElement("devices", duplicates.Select(g => XElement.Parse(g.Key))));
基本上,重复的IGrouping
集合使用元素的字符串表示作为键并保存所有重复的节点。
【讨论】:
以上是关于查找重复的 XML 节点并最小化 XML 结构和大小的主要内容,如果未能解决你的问题,请参考以下文章
使用 jQuery 查找 XML 节点并放入现有的 HTML 表中