You need to enable JavaScript to run this app. 如何使用XML::LibXML解析Apple PLIST格式的XML字典结构
优惠活动
大模型
产品
解决方案
定价
更多

如何使用XML::LibXML解析Apple PLIST格式的XML字典结构

问题原因
  • key无输出:你的代码尝试读取<dict>节点的key属性,但Apple PLIST格式里key是独立的子节点,不是父节点<dict>的属性,所以findvalue('@key')永远返回空值。
  • value拼接输出:textContent方法会返回当前节点及其所有后代节点的全部文本内容拼接结果,你直接对<dict>节点调用该方法,自然会把该字典下所有key、value的文本全部拼在一起输出。

PLIST的字典结构逻辑是固定的:每个<dict>节点下的子节点严格按[key节点, value节点]成对出现,value节点可以是string、integer、array、dict、布尔等类型。


修复方案

方案1:基于XML::LibXML手动适配PLIST结构

适合不想额外安装其他模块的场景,递归实现适配PLIST的所有嵌套结构:

#!/usr/bin/perl
use strict;
use warnings;
use XML::LibXML;

my $filename = '/Users/user/path/to/file';
# 加载XML文件
my $xml = XML::LibXML->load_xml(location => $filename);

# 递归解析PLIST节点的通用函数
sub parse_plist_node {
    my ($node) = @_;
    my $node_type = $node->nodeName;
    # 解析字典类型
    if ($node_type eq 'dict') {
        my %dict;
        # 跳过空白节点,只取有效子节点
        my @children = $node->nonBlankChildNodes();
        # 按key/value成对遍历
        for (my $i = 0; $i < @children; $i += 2) {
            my $key_node = $children[$i];
            next unless $key_node->nodeName eq 'key';
            my $key = $key_node->textContent;
            my $value_node = $children[$i + 1];
            $dict{$key} = parse_plist_node($value_node);
        }
        return \%dict;
    }
    # 解析数组类型
    elsif ($node_type eq 'array') {
        my @array;
        for my $child ($node->nonBlankChildNodes()) {
            push @array, parse_plist_node($child);
        }
        return \@array;
    }
    # 解析布尔类型
    elsif ($node_type eq 'true' || $node_type eq 'false') {
        return $node_type eq 'true' ? 1 : 0;
    }
    # 解析string、integer等基础类型,直接返回文本值
    else {
        return $node->textContent;
    }
}

# 解析PLIST根字典
my $root_dict = $xml->findnodes('//plist/dict')->shift;
my $plist_data = parse_plist_node($root_dict);

# 测试输出:打印所有快捷短语的缩写和使用次数
for my $clipping (@{$plist_data->{Clippings}}) {
    print "快捷缩写:$clipping->{Abbreviation},总使用次数:$clipping->{TotUsed}\n";
}

方案2:使用专门的PLIST解析模块

直接用CPAN的Mac::PropertyList模块,不需要手动处理XML结构,解析更稳定:

#!/usr/bin/perl
use strict;
use warnings;
use Mac::PropertyList qw(parse_plist_file);

my $filename = '/Users/user/path/to/file';
# 直接解析PLIST文件为Perl结构
my $plist_data = parse_plist_file($filename);

# 测试输出,调用value方法取实际值
for my $clipping (@{$plist_data->{Clippings}->value}) {
    print "快捷缩写:".$clipping->{Abbreviation}->value.",总使用次数:".$clipping->{TotUsed}->value."\n";
}

内容的提问来源于stack exchange,提问作者Polo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 00:45:05