使用 XML::LibXML 向元素添加新的 class

Add new class to an element using XML::LibXML

我有一个简单的 HTML 片段如下:

<div class="out"><p class="a">This is a paragraph. <p class="b">another</p></p></div>

我需要向外部 p 元素添加一个新的 class b,从而产生以下预期结果:

<div class="out"><p class="a b">This is a paragraph. <p class="b">another</p></p></div>

内部 p 元素应保持不变。

这可能吗?

找到正确的 元素 并使用 setAttribute 方法更改其属性。

下面的代码使用了评论中阐明的要求:感兴趣的段落是 div 下面的第一个段落,如果它的属性 class 存在或创建,则需要附加它。

use warnings;
use strict;
use feature 'say';

use XML::LibXML;

my $xml = q(<div class="out"><p class="a">This is a paragraph. )
        . q(<p class="b">another</p></p></div>);  #/

my $doc = XML::LibXML->load_xml(string => $xml);

my @nodes = $doc->findnodes('//p');

for my $node (@nodes) { 
    if ($node->parentNode->nodeName eq 'div') {
        my $attr_val = $node->getAttribute('class');
        $node->setAttribute(
            class => ($attr_val ? "$attr_val " : '') . 'b'
        );
    }   
}

say $doc;

这仍然假设 p 没有同级段落(因此直接在同一个 div 之下),或者如果有,它们也应该以相同的方式进行更改。如果不是这种情况,那么应该识别所有这些兄弟姐妹并跳过它们。

首先搜索 p,然后检查节点的父节点,以防出现一些细微的改进(“是的,pdiv,但 ..." 的边缘情况除外。但是,如果这不是问题,并且严格来说是 div 下的 p,那么最好直接使用

my @nodes = $doc->findnodes('//div/p');

然后追加到 class 属性或以与上述相同的方式创建它。

以上打印

<?xml version="1.0"?>
<div class="out"><p class="a b">This is a paragraph. <p class="b">another</p></p></div>