Perl 使用XML::LibXML编写XML时,如何创建要追加的节点?

Perl 使用XML::LibXML编写XML时,如何创建要追加的节点?,perl,libxml2,Perl,Libxml2,我正在创建一个XML文档,并在循环中向其添加一个复杂的节点,类似于下面的示例 下面的代码可以工作,但在创建$row\u模板的过程中感觉有些笨拙。有没有更具体的方法来创建文档片段,以便从xml字符串中重用 use 5.022; use warnings; use XML::LibXML; my $xml = '<?xml version="1.0"?><RootNode><Outer1><Outer2/></Outer1></Ro

我正在创建一个XML文档,并在循环中向其添加一个复杂的节点,类似于下面的示例

下面的代码可以工作,但在创建
$row\u模板的过程中感觉有些笨拙。有没有更具体的方法来创建文档片段,以便从xml字符串中重用

use 5.022;
use warnings;
use XML::LibXML;

my $xml = '<?xml version="1.0"?><RootNode><Outer1><Outer2/></Outer1></RootNode>';
my $row_parent_xpath = '//Outer2';
my $row_xml = '<DetailNode><Field1/><Field2/></DetailNode>';

# create the document
my $doc = XML::LibXML->load_xml('string' => $xml);
# find where we will be inserting nodes
my ($parent) = $doc->findnodes($row_parent_xpath);

# create a template for the nodes to insert
my $row_template = XML::LibXML->load_xml('string' => $row_xml)->documentElement;
$row_template->setOwnerDocument($doc);

for my $row_data ({field1=>'Foo',field2=>'Bar'}, {field1=>'Baz',field2=>'Quux'}) {
    my $row = $row_template->cloneNode(1);
    $parent->appendChild($row);
    $_->appendChild($doc->createTextNode($row_data->{field1})) for $row->findnodes('Field1');
    $_->appendChild($doc->createTextNode($row_data->{field2})) for $row->findnodes('Field2');
}

say $doc->toString(1);
使用5.022;
使用警告;
使用XML::LibXML;
我的$xml='';
我的$row_parent_xpath='//Outer2';
my$row_xml='';
#创建文档
我的$doc=XML::LibXML->load_XML('string'=>$XML);
#找到要插入节点的位置
my($parent)=$doc->findnodes($row\u parent\u xpath);
#为要插入的节点创建模板
我的$row\u模板=XML::LibXML->load\u XML('string'=>$row\u XML)->documentElement;
$row_模板->设置所有者文档($doc);
对于我的$row_数据({field1=>'Foo',field2=>'Bar'},{field1=>'Baz',field2=>'qux'}){
my$row=$row\u模板->克隆节点(1);
$parent->appendChild($row);
$row->FINDNODE('field1')的$_u->appendChild($doc->createTextNode($row_data->{field1}));
$row->FINDNODE('field2')的$\->appendChild($doc->createTextNode($row\\数据->{field2}));
}
说$doc->toString(1);
输出:

<?xml version="1.0"?>
<RootNode>
  <Outer1>
    <Outer2>
      <DetailNode>
        <Field1>Foo</Field1>
        <Field2>Bar</Field2>
      </DetailNode>
      <DetailNode>
        <Field1>Baz</Field1>
        <Field2>Quux</Field2>
      </DetailNode>
    </Outer2>
  </Outer1>
</RootNode>

福
酒吧
巴兹
库克斯

libxml2有一个文件,它还接受一个文档。LibXML有,但不允许设置文档。我不确定您是否必须调用
setOwnerDocument
。在附加克隆节点时,应该自动设置所有者文档。

这基本上就是我生成XML的方式。Mojo::DOM方法可以让它稍微好一点,但通常我最终只使用XML转义模板器(比如带有auto_escape=>1的Mojo::Template)。为什么不创建一个为您想要做的事情提供合适接口的子对象呢?您可以编写
$->appendText(…)
,而不是
$->appendChild($doc->createTextNode(…)
。另一个有用的方法是
appendTextChild
。除此之外,我不确定您希望如何简化代码。@n困扰我的问题是没有看到创建文档片段的东西,必须调用load_xml,然后扔掉它创建的文档,只保留根元素。libxml有一个文档片段类型,但似乎没有直接创建文档片段的方法,也没有解析xml片段并只生成现有文档所拥有的节点的方法,这似乎是错误的。libxml2也有一个文档。LibXML有,但不允许设置文档。总之,您不必调用
setOwnerDocument
,但如果您这样做,它的性能会更好。