XML(LibXML):用具有相同内容的xhtml:h2标记替换xhtml:h1标记的最简单方法
我正在使用Perl/CPAN来解析和操作一个有效的XHTML1.1文档,该文档包含几个嵌套的标记,其中包含,等等 现在,我正在从那里提取div,它们的标题以开头,我想转换为以开头(即:h2)→ h1;h3→ h2;h4→ h3等) 如何使用XML::LibXML实现这一点 以下是我到目前为止的情况:XML(LibXML):用具有相同内容的xhtml:h2标记替换xhtml:h1标记的最简单方法,xml,perl,libxml2,Xml,Perl,Libxml2,我正在使用Perl/CPAN来解析和操作一个有效的XHTML1.1文档,该文档包含几个嵌套的标记,其中包含,等等 现在,我正在从那里提取div,它们的标题以开头,我想转换为以开头(即:h2)→ h1;h3→ h2;h4→ h3等) 如何使用XML::LibXML实现这一点 以下是我到目前为止的情况: foreach my $h_idx (2 .. 6) { foreach my $h_tag ($scene_xpc->findnodes(qq{//xhtml
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);
}
}
正如您从变量名
$scene\u xpc
中猜到的,您需要定义一个XML::LibXML::XPathContext
,它定义了xhtml
名称空间。此后,您可以像使用普通的XML::LibXML
对象一样使用该上下文,但现在可以在元素和属性名称中指定已注册的名称空间
我不清楚为什么要克隆每个节点。据我所知,您只需在每个节点上执行setNodeName
。所需的只是localname:元素将保留其原始名称空间
这个简短的节目展示了这个想法
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;
您好,Borodin,谢谢您的评论-这让我找到了正确的方向,尽管我的代码现在更复杂了,因为XPath是错误的(它应该是“xhtml:h2”而不是“//xhtml:h2”)。抛开这一点不谈,您的代码对我的s///er这件事来说有点太聪明了。我更喜欢用整数。但再次感谢你。