如何按name属性对Android项目的appfilter.xml进行字母排序?
按name属性对appfilter.xml的item标签排序
需要给Android项目中appfilter.xml的<item>标签按name属性的字母顺序排序,但VS Code默认排序命令只会按component属性的字符顺序排列,无法满足需求。
未排序的原始内容
<item component="ComponentInfo{adriandp.ninedash/adriandp.view.main.view.MainActivity}" drawable="nine_dash" name="Nine Dash"/> <item component="ComponentInfo{ai.asleep.android_aaron/ai.asleep.android_aaron.presentation.splash.SplashActivity}" drawable="generic_moon" name="Sleep Tracker"/> <item component="ComponentInfo{air.com.shirogames.evoland12/air.com.shirogames.evoland12.AIRAppEntry}" drawable="evoland" name="Evoland"/> <item component="ComponentInfo{air.com.unit9.bkFrApp/air.com.unit9.bkFrApp.AppEntry}" drawable="burger_king" name="Burger King"/> <item component="ComponentInfo{air.com.unit9.bkFrApp/air.com.unit9.bkFrApp.MainActivity}" drawable="burger_king" name="Burger King"/> <item component="ComponentInfo{alarm.clock.calendar.reminder.pro/home.Activity_List}" drawable="reminder_pro" name="Reminder Pro"/> <item component="ComponentInfo{alarm.clock.calendar.reminder/home.Activity_List}" drawable="reminder_pro" name="Reminder"/> <item component="ComponentInfo{allterco.bg.shelly/allterco.bg.shelly.activities.MainActivity}" drawable="shelly" name="Shelly"/> <item component="ComponentInfo{androidx.compose.material.catalog/androidx.compose.material.catalog.CatalogActivity}" drawable="material_catalog" name="Compose Material Catalog"/> <item component="ComponentInfo{ani.saikou.beta/ani.saikou.MainActivity}" drawable="saikou" name="Saikou β"/> <item component="ComponentInfo{app.accrescent.client/app.accrescent.client.ui.MainActivity}" drawable="generic_moon" name="Accrescent"/> <item component="ComponentInfo{app.attestation.auditor/app.attestation.auditor.AttestationActivity}" drawable="grapheneos_auditor" name="Auditor"/> <item component="ComponentInfo{app.fedilab.nitterizeme/app.fedilab.nitterizeme.activities.MainActivity}" drawable="trust_wallet" name="Trust Wallet"/> <item component="ComponentInfo{app.fedilab.nitterizeme/app.fedilab.nitterizeme.MainActivity}" drawable="trust_wallet" name="Trust Wallet"/> <item component="ComponentInfo{app.grapheneos.apps/app.grapheneos.apps.ui.MainActivity}" drawable="grapheneos_apps" name="GrapheneOS Apps"/> <item component="ComponentInfo{app.grapheneos.apps/org.grapheneos.apps.client.ui.container.MainActivity}" drawable="grapheneos_apps" name="Apps"/>
期望的排序结果
<item component="ComponentInfo{app.accrescent.client/app.accrescent.client.ui.MainActivity}" drawable="generic_moon" name="Accrescent"/> <item component="ComponentInfo{app.grapheneos.apps/org.grapheneos.apps.client.ui.container.MainActivity}" drawable="grapheneos_apps" name="Apps"/> <item component="ComponentInfo{app.attestation.auditor/app.attestation.auditor.AttestationActivity}" drawable="grapheneos_auditor" name="Auditor"/> <item component="ComponentInfo{air.com.unit9.bkFrApp/air.com.unit9.bkFrApp.AppEntry}" drawable="burger_king" name="Burger King"/> <item component="ComponentInfo{air.com.unit9.bkFrApp/air.com.unit9.bkFrApp.MainActivity}" drawable="burger_king" name="Burger King"/> <item component="ComponentInfo{androidx.compose.material.catalog/androidx.compose.material.catalog.CatalogActivity}" drawable="material_catalog" name="Compose Material Catalog"/> <item component="ComponentInfo{air.com.shirogames.evoland12/air.com.shirogames.evoland12.AIRAppEntry}" drawable="evoland" name="Evoland"/> <item component="ComponentInfo{app.grapheneos.apps/app.grapheneos.apps.ui.MainActivity}" drawable="grapheneos_apps" name="GrapheneOS Apps"/> <item component="ComponentInfo{adriandp.ninedash/adriandp.view.main.view.MainActivity}" drawable="nine_dash" name="Nine Dash"/> <item component="ComponentInfo{alarm.clock.calendar.reminder.pro/home.Activity_List}" drawable="reminder_pro" name="Reminder Pro"/> <item component="ComponentInfo{alarm.clock.calendar.reminder/home.Activity_List}" drawable="reminder_pro" name="Reminder"/> <item component="ComponentInfo{ani.saikou.beta/ani.saikou.MainActivity}" drawable="saikou" name="Saikou β"/> <item component="ComponentInfo{allterco.bg.shelly/allterco.bg.shelly.activities.MainActivity}" drawable="shelly" name="Shelly"/> <item component="ComponentInfo{ai.asleep.android_aaron/ai.asleep.android_aaron.presentation.splash.SplashActivity}" drawable="generic_moon" name="Sleep Tracker"/> <item component="ComponentInfo{app.fedilab.nitterizeme/app.fedilab.nitterizeme.activities.MainActivity}" drawable="trust_wallet" name="Trust Wallet"/> <item component="ComponentInfo{app.fedilab.nitterizeme/app.fedilab.nitterizeme.MainActivity}" drawable="trust_wallet" name="Trust Wallet"/>
解决方案
方法1:VS Code正则辅助排序
- 选中所有需要排序的
<item>行 - 打开查找替换面板(Ctrl+H),勾选「正则表达式」选项
- 第一步:提取name值到行首
- 查找:
^(.*name=")([^"]+)(".*)$ - 替换为:
$2|||$1$2$3
执行替换后,每行开头会加上name属性的值和分隔符|||
- 查找:
- 选中处理后的所有行,右键选择「排序行」→「按升序排序」
- 第二步:恢复原格式
- 查找:
^[^|]+|||(.*)$ - 替换为:
$1
执行替换后,即可去掉行首的name值和分隔符,得到按name排序后的内容
- 查找:
方法2:Python脚本批量处理
编写简单脚本直接解析XML并排序,避免手动操作:
import xml.etree.ElementTree as ET # 加载目标XML文件,替换为你的appfilter.xml路径 tree = ET.parse('appfilter.xml') root = tree.getroot() # 按name属性的小写字母排序,避免大小写影响顺序 root[:] = sorted(root, key=lambda x: x.get('name').lower()) # 设置缩进并保存排序后的文件,生成新文件避免覆盖原文件 ET.indent(tree, space=" ") tree.write('appfilter_sorted.xml', encoding='utf-8', xml_declaration=True)
运行脚本后,会在同目录生成排序好的appfilter_sorted.xml文件。
方法3:命令行工具xmllint排序
如果系统已安装xmllint(Linux/macOS默认自带,Windows可通过WSL或安装工具包获取),可直接用命令行:
# 提取并排序item标签,输出到新文件 xmllint --format --sort -xpath '/resources/item' appfilter.xml > sorted_items.xml
之后将sorted_items.xml中的排序后的<item>标签复制回原appfilter.xml对应位置即可。
内容的提问来源于stack exchange,提问作者Chefski
相关产品推荐
相关产品推荐

