XML::Twig - 没有破坏结构的 set_text

标签 xml perl xml-twig

XML::Twig 使用 set_text 方法 - 有一个警告:

set_text ($string) Set the text for the element: if the element is a PCDATA, just set its text, otherwise cut all the children of the element and create a single PCDATA child for it, which holds the text.

因此,如果我想做一些简单的事情,比如 - 比如说 - 更改我的 XML::Document 中所有文本的大小写:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my $twig = XML::Twig->new(
    'pretty_print'  => 'indented_a',
    'twig_handlers' => {
        '_all_' => sub {
            my $newtext = $_->text_only;
            $newtext =~ tr/[a-z]/[A-Z]/;
            $_->set_text($newtext);
        }
    }
);
$twig->parse( \*DATA );
$twig->print;

__DATA__
<root>
    <some_content>fish
        <a_subnode>morefish</a_subnode>
    </some_content>
    <some_more_content>cabbage</some_more_content>
</root>

这 - 因为 set_text 替换了 child - 被破坏成:

<root></root>

但如果我只关注一个(底层)节点(例如 a_subnode),那么它工作正常。

是否有一种优雅的方式来替换/转换元素内的文本而不破坏其下方的数据结构?我的意思是,我可以对是否存在 child 或类似的东西进行测试,但是......似乎应该有更好的方法来做到这一点。 (也许是不同的库?)

(为了清楚起见 - 这是我音译文档中所有文本的示例,我的实际用例相当复杂,但仍然是“关于”就地文本转换)。

我正在考虑节点剪切/和/粘贴方法(剪切所有子节点、替换文本、粘贴所有子节点),但这似乎是一种低效的方法。

最佳答案

与其在 _all_ 上使用处理程序,不如尝试仅在文本元素上使用它:#TEXT,并将 text_only 更改为 文本。它应该工作。

更新:或者在创建 Twig 时使用char_handler 选项:char_handler => sub { uc shift }, 而不是处理程序.

关于XML::Twig - 没有破坏结构的 set_text,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30802600/

相关文章:

android - 使 android 按钮的背景半透明,

xml - 哪些浏览器支持 XSLT 2.0?

arrays - 在 Perl 中逐行比较两个字符串

xml - 如何从 XML::Twig 元素获取原始 XML 代码

c# - .Net Core 使用 IEnumerables<T> 序列化对象以另存为 XML

java - 解析 XML 时出现 IllegalStateException?

perl - Perl,DBD::Oracle和Oracle 10g的字符集问题

arrays - 将哈希键转换为数组

xml - 如何使用 XML::Twig 从 URL 中提取一些 XML 数据?

perl - 如何使用 XML Twig 将修改后的树保存到磁盘中