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

Posted

技术标签:

【中文标题】(perl) Xerces 验证如何访问 http 模式?【英文标题】:How does (perl) Xerces validation access http schemas? 【发布时间】:2021-07-04 07:36:00 【问题描述】:

这个自包含示例(路径名:/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 $validvalid\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 的管理员告诉我,在执行手动wget 时,他没有看到任何试图到达http://www.w3schools.com 的东西。这似乎 Xerces 根本不费心去获取那个 URL。

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

【问题讨论】:

http:80 工作正常 - 在你的代码中你使用https: (443) 感谢@clamp 观看。 25 行的架构实际上是在 http 上(是该行空格之后的第二个 url)。其他网址(第 23 / 24 行的 http 和 https 以及第 25 行的第一个似乎没有发挥真正的作用,因为正如所说的交换第 25 和 27 行,它们都仍然存在并且验证有效)。将所有 url 设置为 http(w3schools.com 甚至提供它们)和使用 https(因为 B-NOK 有 443 个打开,我只是将 http 用于架构,因为 wget 给了我进一步确认它工作正常,所以没有任何变化。 不要告诉我们它不起作用 - 告诉我们它是如何失败的。诊断总是从观察症状开始。 meta.***.com/questions/280478/why-not-w3schools-com - 我认为它们仍然不是一个很好的资源。 谢谢@MichaelKay。这是一个 C 库。逐步调试我的示例,您只能达到这一点:metacpan.org/release/XML-Validate/source/lib/XML/Validate/…(作为参考,我在第 59 行将其称为文件V)并且没有办法更进一步。在A-OK 中,原子指令不会失败并转到下一条指令(第 61 行的同一文件V),而在B-NOK 上出现异常(在库的二进制文件中),我发现自己在下一条指令(同一文件V 第 141 行) 【参考方案1】:

来源:

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 设置仅在严格验证模式下为真。

使用以下方法应该可以解决问题:

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

【讨论】:

谢谢@ikegami。该代码是文件V(行83)(文件V是我之前在回复@MichaelKay时使用的参考,V的缩写。strict_validation已经设置为@默认情况下为 987654328@ (fileV line 16) 并且严格的分支确实是调试时采用的分支。我确认我为本地和远程模式都输入了该分支。如上所述有本地和远程之间没有区别直到文件V59 行远程方案失败。 我没有得到详细信息,但 B-NOK 服务器和后面的网络设置已经执行,目前解决了我的问题。尽管如此,我还是将其标记为解决方案,因为即使偶然strict_validation(如我之前的回答中所述)已经设置为1,但这是区分访问模式的值(本地和远程,等等http(s) ),因此将其显式设置为 1 可以保证在任何情况下都具有正确的行为,因此这是对我原来问题的好答案。

以上是关于(perl) Xerces 验证如何访问 http 模式?的主要内容,如果未能解决你的问题,请参考以下文章

带有验证器的 Perl 工作流模块

如何使用com.sun.org.apache.xerces.internal.parsers.SAXParser在SAXBuilder中禁用XML外部实体(XEE)处理

用xerces-c来进行xml schema校验

Perl LDAP 搜索作为 CN 属性的用户

如何验证 Perl 中的数组(列表)中是不是存在值?

Perl:如何验证对“XML::eXistDB::RPC”的成功调用