基于名称/值对计算元素关联数:按SerialNum统计SkuID总数
统计XML中每个SerialNum对应的SkuID总数
首先我先补全一个合理的XML结构假设(毕竟你给出的片段只展示了SerialNum部分)——我默认每个<Skid>节点里同时包含SerialNum和SkuID的<NameValue>对,类似这样:
<?xml version="1.0" encoding="UTF-8"?> <root> <Skid> <NameValuePairs> <NameValue> <ID>SerialNum</ID> <Value>12345678</Value> </NameValue> <NameValue> <ID>SkuID</ID> <Value>S001</Value> </NameValue> </NameValuePairs> </Skid> <Skid> <NameValuePairs> <NameValue> <ID>SerialNum</ID> <Value>12345678</Value> </NameValue> <NameValue> <ID>SkuID</ID> <Value>S002</Value> </NameValue> </NameValuePairs> </Skid> <Skid> <NameValuePairs> <NameValue> <ID>SerialNum</ID> <Value>87654321</Value> </NameValue> <NameValue> <ID>SkuID</ID> <Value>S003</Value> </NameValue> </NameValuePairs> </Skid> </root>
下面分两种常见场景给你实现方案:统计含重复的SkuID总数,或者去重后的唯一SkuID数量。
方法1:用Python实现(灵活易扩展)
Python的xml.etree.ElementTree模块能轻松搞定XML解析和统计,代码逻辑很直观:
场景A:统计含重复的SkuID总数
import xml.etree.ElementTree as ET # 解析XML文件(如果是字符串输入,改用ET.fromstring(xml_str)) tree = ET.parse('your_sku_file.xml') root = tree.getroot() # 用字典存统计结果:key是SerialNum,value是对应SkuID的总个数 serial_sku_total = {} for skid in root.findall('Skid'): serial_num = None sku_id = None # 遍历当前Skid下的所有NameValue对,提取SerialNum和SkuID for name_value in skid.findall('.//NameValue'): id_type = name_value.find('ID').text id_value = name_value.find('Value').text if id_type == 'SerialNum': serial_num = id_value elif id_type == 'SkuID': sku_id = id_value # 确保两个值都存在才统计 if serial_num and sku_id: if serial_num in serial_sku_total: serial_sku_total[serial_num] += 1 else: serial_sku_total[serial_num] = 1 # 打印结果 print("每个SerialNum对应的SkuID总数(含重复):") for serial, count in serial_sku_total.items(): print(f"SerialNum {serial}: {count} 个SkuID")
场景B:统计去重后的唯一SkuID数量
如果同一个SerialNum下可能出现重复的SkuID,要统计唯一值的话,把字典的value换成集合就行:
import xml.etree.ElementTree as ET tree = ET.parse('your_sku_file.xml') root = tree.getroot() # key是SerialNum,value是存储唯一SkuID的集合 serial_unique_sku = {} for skid in root.findall('Skid'): serial_num = None sku_id = None for name_value in skid.findall('.//NameValue'): id_type = name_value.find('ID').text id_value = name_value.find('Value').text if id_type == 'SerialNum': serial_num = id_value elif id_type == 'SkuID': sku_id = id_value if serial_num and sku_id: if serial_num not in serial_unique_sku: serial_unique_sku[serial_num] = set() serial_unique_sku[serial_num].add(sku_id) # 打印结果:集合的长度就是唯一SkuID的数量 print("每个SerialNum对应的唯一SkuID数量:") for serial, skus in serial_unique_sku.items(): print(f"SerialNum {serial}: {len(skus)} 个唯一SkuID")
方法2:用XSLT实现(纯XML原生处理)
如果你更习惯用XML生态的工具,XSLT可以直接把XML转换为统计结果,适合不需要写代码的场景:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="UTF-8"/> <!-- 按SerialNum定义分组键 --> <xsl:key name="serialGroup" match="Skid" use=".//NameValue[ID='SerialNum']/Value"/> <xsl:template match="/"> <xsl:text>每个SerialNum对应的SkuID总数(含重复): </xsl:text> <!-- 遍历所有唯一的SerialNum分组 --> <xsl:for-each select="root/Skid[generate-id() = generate-id(key('serialGroup', .//NameValue[ID='SerialNum']/Value)[1])]"> <xsl:variable name="currentSerial" select=".//NameValue[ID='SerialNum']/Value"/> <!-- 统计当前分组下的SkuID总数 --> <xsl:variable name="skuCount" select="count(key('serialGroup', $currentSerial)//NameValue[ID='SkuID'])"/> <xsl:text>SerialNum </xsl:text> <xsl:value-of select="$currentSerial"/> <xsl:text>: </xsl:text> <xsl:value-of select="$skuCount"/> <xsl:text> 个SkuID </xsl:text> </xsl:for-each> </xsl:template> </xsl:stylesheet>
把这个XSLT文件和你的XML放在一起,用支持XSLT的工具(比如浏览器、Saxon处理器)转换就能得到结果。如果要统计唯一SkuID,需要升级到XSLT 2.0及以上,用distinct-values()函数处理。
核心逻辑说明
不管用哪种方案,核心步骤都是:
- 遍历所有
<Skid>节点,提取每个节点对应的SerialNum和SkuID。 - 按
SerialNum分组,对组内的SkuID进行计数(或去重后计数)。 - 输出每个SerialNum对应的最终统计结果。
如果你的XML结构和我假设的有差异(比如SkuID的路径不同),只需要调整代码里的节点查找路径就行。
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

