You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用XML::LibXML保留XML字符引用的往返一致性?

问题描述

我在解析包含多个实体的XML文件时,需要修改部分XML属性、值、节点名称后重新保存,但当前处理过程中XML字符引用会被自动解码,输出不符合预期:

XML文件片段

<?xml version="1.0" encoding="UTF-8"?>
<root>
<copyright-statement>Copyright &#x00A9;The authors 2024.</copyright-statement>
</root>

Perl代码片段

use XML::LibXML;
use File::Slurp;
open my $fh, '<', $ARGV[0] or die $!;
binmode $fh;
my $dom = XML::LibXML->load_xml(IO => $fh);
my $root = $dom->documentElement();
my @cp = $root->findnodes('//copyright-statement');
write_file('file_name.txt', $cp[0]->textContent);

输出差异

  • 期望输出:Copyright &#x00A9;The authors 2024.
  • 实际输出:Copyright ©The authors 2024.

请问需对上述Perl代码做哪些修改,才能保留原XML字符引用?


解决方案

XML::LibXML的textContent方法会自动解码XML字符引用,要保留原始的字符引用,需要调整XML加载方式和内容获取逻辑:

修改后的代码如下:

use XML::LibXML;
use File::Slurp;

open my $fh, '<', $ARGV[0] or die $!;
binmode $fh;
# 加载XML时禁用实体自动展开
my $dom = XML::LibXML->load_xml(IO => $fh, expand_entities => 0);
my $root = $dom->documentElement();
my @cp = $root->findnodes('//copyright-statement');

# 获取节点下所有子文本节点的原始内容并拼接
my $raw_content = join '', map { $_->toString() } $cp[0]->childNodes();

write_file('file_name.txt', $raw_content);

修改要点说明

  1. 禁用实体展开:在load_xml中添加expand_entities => 0参数,阻止解析器自动解码字符引用。
  2. 获取原始文本内容:通过childNodes()遍历目标节点的子节点,调用toString()获取每个文本节点的原始未解码内容,拼接后得到保留字符引用的字符串。

处理后即可得到符合预期的输出。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 03:56:09