Perl实现移除XML指定key的entry节点并保留原有空行
实现保留原空行的XML entry节点删除功能
优先方案:使用XML解析模块(推荐)
用正则处理XML容易出现各种边界问题(比如CDATA内容、属性顺序变化、嵌套标签干扰),因此推荐使用专业的XML解析模块XML::LibXML来实现,既能精准删除节点,又能保留原文件的空白结构。
依赖安装
先安装XML::LibXML模块:
cpanm XML::LibXML
实现代码
use XML::LibXML; use File::Slurp; sub remove_xml_entries { my ($filename, @keys) = @_; # 读取原始文件内容,保留换行结构 my $xml_content = read_file($filename); # 初始化XML解析器,开启空白保留 my $parser = XML::LibXML->new({ preserve_blanks => 1, load_ext_dtd => 0, }); my $doc = $parser->parse_string($xml_content); # 构建待删除key的哈希集合,提升查找效率 my %target_keys = map { $_ => 1 } @keys; # 遍历所有entry节点 my $xpc = XML::LibXML::XPathContext->new($doc); foreach my $entry ($xpc->findnodes('//entry')) { my $entry_key = $entry->getAttribute('key'); next unless exists $target_keys{$entry_key}; # 删除节点前后的空白文本节点,避免残留空行 my $prev_node = $entry->previousSibling; while ($prev_node && $prev_node->nodeType == XML_TEXT_NODE && $prev_node->data =~ /^\s*$/) { $prev_node->parentNode->removeChild($prev_node); $prev_node = $entry->previousSibling; } my $next_node = $entry->nextSibling; while ($next_node && $next_node->nodeType == XML_TEXT_NODE && $next_node->data =~ /^\s*$/) { $next_node->parentNode->removeChild($next_node); $next_node = $entry->nextSibling; } # 删除目标entry节点 $entry->parentNode->removeChild($entry); } # 生成保留原始格式的XML并写入文件 write_file($filename, $doc->toString(1)); }
代码说明
preserve_blanks => 1:让解析器保留原始的空白节点,确保原文件的空行不会被破坏- 删除目标节点时,同时清理其前后的空白文本节点,避免删除后残留空行
- 用XPath精准定位所有
entry节点,不受属性顺序或节点格式影响
备选方案:改进正则实现(仅限简单XML场景)
如果不想依赖XML模块,可以使用改进后的正则,但仅适用于结构简单、无嵌套干扰的XML文件:
use File::Slurp; sub remove_entries_with_regex { my ($filename, @keys) = @_; my $file_content = read_file($filename); # 构建匹配待删除key的正则,转义特殊字符避免匹配错误 my $key_pattern = join('|', map { quotemeta($_) } @keys); # 匹配目标entry节点及其直接关联的空白,不影响其他空行 $file_content =~ s/^\s*<entry\s+key\s*=\s*"($key_pattern)"[^>]*>.*?<\/entry>\s*$//gms; write_file($filename, $file_content); }
正则说明
gms修饰符:全局匹配、多行模式(让^和$匹配每行首尾)、点号匹配换行符- 仅删除
entry节点及其前后的空白,不会触碰文件中其他位置的空行 - 局限性:无法处理属性顺序变化、CDATA中包含类似标签、节点嵌套复杂的情况
内容的提问来源于stack exchange,提问作者Kautuk Raj
相关产品推荐
相关产品推荐

