(perl) Xerces 验证如何访问 http 模式?

问题描述

这个自包含示例(路径名:/root/stef/test.pl)在服务器 A-OK 上工作正常,而在另一台服务器 B-NOK 上不起作用。

      1 use strict;
      2 use XML::Validate::Xerces;
      3
      4 sub main {
      5     my $rsep = $/;
      6     undef $/;
      7     my $xml = <DATA>;
      8     $/ = $rsep;
      9
     10     warn "working on this xml:[\n$xml]";
     11
     12     my %options;
     13     my $validator = new XML::Validate::Xerces(%options);
     14     my $valid = $validator->validate($xml) ? '' : 'in';
     15     warn "Document is ${valid}valid\n";
     16 }
     17
     18 main();
     19
     20 __DATA__
     21 <?xml version="1.0"?>
     22 <note
     23   xmlns="https://www.w3schools.com"
     24   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     25   xsi:schemaLocation="https://www.w3schools.com http://www.w3schools.com/xml/note.xsd">
     26   <!--
     27   xsi:schemaLocation="https://www.w3schools.com file:///root/stef/note.xsd">
     28   -->
     29   <to>Tove</to>
     30   <from>Jani</from>
     31   <heading>Reminder</heading>
     32   <body>Don't forget me this weekend!</body>
     33 </note>

如果我交换行 2527(即我将 http://www.w3schools.com/xml/note.xsd 更改为 file:///root/stef/note.xsd),那么将架构作为本地文件,那么即使在 B-NOK 中它也能正常工作。

当架构在 http 上时,唯一的区别似乎是。

请注意,本地文件是作为 wget http://www.w3schools.com/xml/note.xsd 下载的,因此我不仅知道架构文件内容是相同的(本地和远程),而且 http:80 可以很好地捕捉那里的东西.

我没有做任何特别的事情来让 Xerces 通过 http:80 为服务器 A-OK 工作。 然后我希望在服务器 B-NOK 上什么都不做,让 Xerces 去那里获取模式。

如果/如何指示 Xerces 使用 http,我没有找到明确的信息。它没有内置哪种机制,像 wget 一样下载 URL。 如果我必须添加一些配置变量,我无法理解。 服务器 B-NOK管理员告诉我,在执行手册 http://www.w3schools.com 时,他没有看到任何试图将 wget 分开的东西。这似乎 Xerces 根本不费心去获取那个 URL。

真的提前感谢您的任何提示

解决方法

来源:

if ($strict) {
        TRACE("Using strict validation");
        $DOMparser->setValidationScheme("$XML::Xerces::AbstractDOMParser::Val_Auto");
        $DOMparser->setIncludeIgnorableWhitespace(0);
        $DOMparser->setDoSchema(1);
        $DOMparser->setDoNamespaces(1);
        $DOMparser->setValidationSchemaFullChecking(1);
        $DOMparser->setLoadExternalDTD(1);
        $DOMparser->setExitOnFirstFatalError(1);
        $DOMparser->setValidationConstraintFatal(1);
} else {
        TRACE("Using no validation");
        $DOMparser->setValidationScheme("$XML::Xerces::AbstractDOMParser::Val_Never");
        $DOMparser->setDoSchema(0);
        $DOMparser->setDoNamespaces(0);
        $DOMparser->setValidationSchemaFullChecking(0);
        $DOMparser->setLoadExternalDTD(0);
}

请注意,setLoadExternalDTD 设置仅在严格验证模式下为 true。

使用以下内容应该可以解决问题:

my $validator = XML::Validate::Xerces->new( strict_validation => 1 );