【问题标题】:How to create nodes to append when using XML::LibXML to write XML?使用 XML::LibXML 编写 XML 时如何创建要追加的节点?
【发布时间】:2019-11-27 21:03:47
【问题描述】:

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

以下内容有效,但在创建$row_template 时感觉很笨拙。难道没有更具体的方法来创建一个文档片段以从 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);

输出:

<?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>

【问题讨论】:

  • 这基本上是我所做的任何 XML 生成的方式。 Mojo::DOM new_tag 方法可以让它稍微好一点,但通常我最终只使用 XML 转义模板(如 Mojo::Template 和 auto_escape => 1)。
  • 为什么不创建一个为您想要做的事情提供合适接口的子?
  • 你可以写$_-&gt;appendText(...)而不是$_-&gt;appendChild($doc-&gt;createTextNode(...))。另一个有用的方法是appendTextChild。除此之外,我不确定您希望如何简化代码。
  • @nwellnhof 困扰我的事情是没有看到仅创建文档片段的东西,必须调用 load_xml 然后丢弃它创建的文档并保留根元素。 libxml 具有文档片段类型但似乎没有直接的方法来创建一个,或者解析 xml 片段并仅生成现有文档拥有的节点,这似乎是错误的。
  • libxml2 有xmlParseBalancedChunkMemory,它也接受一个文档。 XML::LibXML 有 parse_balanced_chunk 但这不允许设置文档。 AFAIK,无论如何你都不必打电话给setOwnerDocument,但如果你这样做应该会更好。

标签: perl libxml2


【解决方案1】:

libxml2 有xmlParseBalancedChunkMemory,它也接受一个文档。 XML::LibXML 有 parse_balanced_chunk 但这不允许设置文档。我不确定您是否必须致电setOwnerDocument。附加克隆节点时,应自动设置所有者文档。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 2020-08-05
    • 1970-01-01
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    相关资源
    最近更新 更多