Perl脚本调用xmllint格式化XML文件失败问题求助
修复Perl脚本格式化XML文件的问题
你的脚本存在几个关键逻辑错误,导致无法正确格式化XML文件,以下是问题分析和修正方案:
原脚本的核心问题
- 未读取目标XML文件的内容,
$content变量未初始化就直接使用 - 管道调用
xmllint时,没有捕获格式化后的输出,反而尝试写入未修改的原内容 - 文件打开的编码参数写法错误,Perl中正确的编码指定格式是
>:encoding(utf8)而非>encoding(utf8) - 重复执行了两次格式化逻辑,且两次都未正确处理输出结果
- 使用反引号调用
xmllint时,未处理文件路径含空格的情况,也没有捕获命令执行失败的错误
方案一:修复基于xmllint的脚本
以下是修正后的代码,解决了IPC管道和文件读写的问题:
#!/usr/bin/perl use strict; use warnings; # 检查命令行参数 die "Usage: $0 <csproj_file>\n" unless @ARGV == 1; my $csproj_file = $ARGV[0]; # 读取原文件内容(utf8编码) open my $input_fh, '<:encoding(utf8)', $csproj_file or die "无法读取文件 '$csproj_file': $!"; my $content = do { local $/; <$input_fh> }; close $input_fh; # 调用xmllint并获取格式化后的内容,处理路径特殊字符 my $escaped_file = quotemeta($csproj_file); my $formatted_content = `xmllint --format --recover $escaped_file`; die "xmllint执行失败: $?" if $? != 0; # 将格式化后的内容写入文件(覆盖原文件,utf8编码) open my $output_fh, '>:encoding(utf8)', $csproj_file or die "无法写入文件 '$csproj_file': $!"; print $output_fh $formatted_content; close $output_fh; print "XML文件已成功格式化: $csproj_file\n";
关键修正点
- 先读取原文件内容,确保操作有有效输入
- 使用
quotemeta处理文件路径,避免含空格等特殊字符导致命令执行失败 - 检查
xmllint的退出状态码,捕获执行失败的情况 - 正确指定文件读写的编码格式,避免乱码
方案二:纯Perl实现(无需依赖xmllint)
如果环境无法调用外部工具,可以使用Perl的XML处理模块XML::Twig来格式化XML,无需依赖外部命令:
- 先安装模块(如果未安装):
cpanm XML::Twig
- 格式化脚本:
#!/usr/bin/perl use strict; use warnings; use XML::Twig; die "Usage: $0 <csproj_file>\n" unless @ARGV == 1; my $csproj_file = $ARGV[0]; # 初始化XML解析器,设置格式化参数 my $twig = XML::Twig->new( pretty_print => 'indented', # 缩进格式化 indent_string => ' ', # 用两个空格缩进(可自定义) encoding => 'utf-8' # 指定编码 ); # 解析并格式化XML文件 $twig->parsefile($csproj_file); # 将格式化后的内容写入原文件 open my $output_fh, '>:encoding(utf8)', $csproj_file or die "无法写入文件 '$csproj_file': $!"; $twig->print($output_fh); close $output_fh; print "XML文件已成功格式化: $csproj_file\n";
优势
- 无需依赖外部工具,纯Perl环境即可运行
- 更灵活的格式化配置(可自定义缩进字符、换行方式等)
- 避免IPC管道相关的问题
内容的提问来源于stack exchange,提问作者user3773048
相关产品推荐
相关产品推荐

