12

私のXML(a.xhtml)は次のように始まります

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
...

私のコードは次のように始まります

use XML::XPath;

use XML::XPath::XMLParser;

my $xp = XML::XPath->new(filename => "a.xhtml");

my $nodeset = $xp->find('/html/body//table'); 

これは非常に遅く、DTD ( http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ) の取得に多くの時間を費やしていることがわかります。

Perl XML:: ファミリで HTTP プロキシ サーバーを明示的に宣言する方法はありますか? DTD のローカル コピーを持つように、元のa.xhtmlドキュメントを変更するのは嫌いです。

4

3 に答える 3

15

XML::XPath は XML::Parser に基づいています。XML::Parser には、LWP を使用して外部エンティティ (DTD など) を解決しないオプションがあります。また、XML::XPath を使用すると、XML::Parser objetc を渡して、パーサーとして使用できます。

したがって、これを書くことができます:

my $p = XML::Parser->new( NoLWP => 1);
my $xp= XML::XPath->new( parser => $p, filename => "a.xhtml");

この場合、数値のエンティティとデフォルトのエンティティ (>、<、&、'、および ") を除くすべてのエンティティが失われることに注意してください。パーサーは文句を言いませんが、黙って消えます (テーブルに α; を含めて印刷してみてください)。たとえば)。

実際のところ、積極的に保守されていない XML::XPath を使用するべきではないでしょう。

libxml2 のインストールに問題がなければ、XML::LibXML を試してみてください。どちらも DOM を実装しているため、そのインターフェイスは XML::XPath と非常によく似ています。XML::LibXML は、XML::XPath よりもはるかに強力で、起動も高速です。expat/XML::Parser ベースのモジュールが必要な場合は、XML::Twig を参照することをお勧めします (私がモジュールの作成者であるため、露骨な自己宣伝です。申し訳ありません)。また、HTML/危険な XHTML の場合、HTML::TreeBuilder を使用できます。これは、HTML::TreeBuilder::XPath (これも私によるもの) を追加することで、XPath をサポートします。

于 2008-11-20T10:08:59.793 に答える
3

porneL の応答は、ここで正しいことのようです。(www.w3.org は、私のクエリのそれぞれに応答するのに 30 秒かかり始めました (それがあきらめないとき)、そして XML::XPath が最終的に完全な XHTML セットを取得するとき…!) さらに、mirod の考えはうまくいきます、 それも:

use XML::XPath;
use XML::Catalog;

my $parser = new XML::Parser;
my $catalog_handler = new XML::Catalog("xhtml1-20020801/DTD/xhtml.soc")->get_handler($parser);
$parser->setHandlers("ExternEnt" => $catalog_handler);
my $xp = new XML::XPath(xml => $xml, parser => $parser);

⟨URL: http://www.w3.org/TR/xhtml1/dtds.html ⟩から「XML 宣言と SGML オープン カタログを含む DTD ファイルの完全なセット」のコピーを追加して、お楽しみください!

于 2011-03-08T02:26:57.557 に答える
1

通常、これはローカルXMLカタログを設定することによって行われます。

libxmlベースのパーサーはこれをサポートしているため、mirodのアドバイスに従うと、ネットワークにアクセスしなくても名前付きエンティティを取得して検証を行うことができます。

于 2008-11-19T22:22:54.993 に答える