4

私の人生では、エンティティ処理に関する XML::Twig ドキュメントを理解できません。

HTML::Tidy で生成している XML があります。呼び出しは次のとおりです。

my $tidy = HTML::Tidy->new({
    'indent'          => 1,
    'break-before-br' => 1,
    'output-xhtml'    => 0,
    'output-xml'      => 1,
    'char-encoding'   => 'raw',
});

$str = "foo   bar";
$xml = $tidy->clean("<xml>$str</xml>");

これは以下を生成します:

<html>
  <head>
    <meta content="tidyp for Linux (v1.02), see www.w3.org" name="generator" />
    <title></title>
  </head>
  <body>foo &nbsp; bar</body>
</html>

XML::Twig (当然のことながら) の barfs &nbsp;. XML::Twig を介して実行して、いくつかの変換を行いたい:

my $twig = XML::Twig->new(
  twig_handlers => {... handlers ...}
);

$twig->parse($xml);

$twig->parse行は barfsですが、要素をプログラム&nbsp;で追加する方法がわかりません。私は次のようなことを試しました:&nbsp;

my $entity = XML::Twig::Entity->new("nbsp", "&#160;");
$twig->entity_list->add($entity);
$twig->parse($xml);

...しかし、喜びはありません。

助けてください=)

4

3 に答える 3

6

このような場合の汚いが効率的なトリックは、偽の DTD 宣言を追加することです。

次に、構文解析を行う XML::Parser は、エンティティが DTD で定義されていると想定し、それに対してバーフを行いません。

偽の DTD 宣言を取り除くために、小枝のルートを出力できます。別の宣言が必要な場合は、それを作成して現在の宣言を置き換えます。

#!/usr/bin/perl 

use strict;
use warnings;

use XML::Twig;

my $fake_dtd= '<!DOCTYPE head SYSTEM "foo"[]>'; # foo may not even exist

my $xml='<html>
  <head>
    <meta content="tidyp for Linux (v1.02), see www.w3.org" name="generator" />
    <title></title>
  </head>
  <body>foo &nbsp; bar</body>
</html>';

XML::Twig->new->parse( $fake_dtd . $xml)->root->print;
于 2010-10-27T13:23:39.960 に答える
4
use strict;
use XML::Twig;

my $doctype = '<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html [<!ENTITY nbsp "&#160;">]>';
my $xml = '<html><head><meta content="tidyp for Linux (v1.02), see www.w3.org" name="generator" /><title></title></head><body>foo &nbsp; bar</body></html>';

my $xTwig = XML::Twig->new();

$xTwig->safe_parse($doctype . $xml) or die "Failure to parse XML : $@";

print $xTwig->sprint();
于 2010-10-22T19:24:17.273 に答える
1

もっと良い方法があるかもしれませんが、以下のコードは私のために働きました:

my $filter = sub {
    my $text  = shift;
    my $ascii = "\x{a0}";    # non breaking space
    my $nbsp  = '&nbsp;';
    $text =~ s/$ascii/$nbsp/;
    return $text;
};

XML::Twig->new( output_filter => $filter )
         ->parse_html( $xml )
         ->print;
于 2010-10-22T19:06:05.787 に答える