0

我正在使用 Perl/CPAN XML::LibXML来解析和操作一个有效的 XHTML 1.1 文档,该文档包含多个嵌套的 <div> 标签和 <h1> 、 <h2> 等。

现在,我正在从那里提取 div,它们的标题从 <xhtml:h2 /> 开始,我想将其转换为从 <xhtml:h1 /> 开始(即:h2 → h1 ; h3 → h2 ; h4 → h3 等.)。

如何使用 XML::LibXML 做到这一点?

这是我到目前为止所拥有的:

    foreach my $h_idx (2 .. 6)
    {
        foreach my $h_tag ($scene_xpc->findnodes(qq{//xhtml:h$h_idx}))
        {
            my $replacement = $h_tag->cloneNode(1);
            # TODO : how do I set the name?
            $replacement->set
            $h_tag->replaceNode($replacement);
        }
    }
4

1 回答 1

2

正如您似乎从变量名中猜到的那样$scene_xpc,您需要定义一个定义XML::LibXML::XPathContextxhtml命名空间的变量。此后,您可以像使用普通XML::LibXML对象一样使用该上下文,只是您现在可以在元素和属性名称中指定注册的命名空间。

我不清楚你为什么要克隆每个节点。据我所知,您需要做的就是setNodeName在每个节点上。所需要的只是本地名称:元素将保留其原始名称空间。

这个简短的节目展示了这个想法。

use strict;
use warnings;
use 5.014;    # For non-destructive substitution

use XML::LibXML;

my $filename = 'xhtml.html';

my $xml = XML::LibXML->new;
my $doc = $xml->parse_file($filename);

my $xpc = XML::LibXML::XPathContext->new($doc);
$xpc->registerNs('xhtml', 'http://www.w3.org/1999/xhtml');

for my $head ('h2' .. 'h6') {
  my $newhead = $head =~ s/(\d)/$1-1/er;
  for my $node ($xpc->findnodes("//xhtml:$head")) {
    $node->setNodeName($newhead);
  }
}

print $doc->toString;
于 2013-03-21T09:16:29.990 回答