(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>
如果我交换行 25 和 27(即我将 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) 并且严格的分支确实是调试时采用的分支。我确认我为本地和远程模式都输入了该分支。如上所述有本地和远程之间没有区别直到文件V
第 59 行远程方案失败。
我没有得到详细信息,但 B-NOK 服务器和后面的网络设置已经执行,目前解决了我的问题。尽管如此,我还是将其标记为解决方案,因为即使偶然strict_validation
(如我之前的回答中所述)已经设置为1,但这是区分访问模式的值(本地和远程,等等http(s) ),因此将其显式设置为 1 可以保证在任何情况下都具有正确的行为,因此这是对我原来问题的好答案。以上是关于(perl) Xerces 验证如何访问 http 模式?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用com.sun.org.apache.xerces.internal.parsers.SAXParser在SAXBuilder中禁用XML外部实体(XEE)处理