- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想加快根据同一个 XML 架构 (XSD) 验证一批 XML 文件的过程。唯一的限制是我在 PHP 环境中。
我当前的问题是我要验证的模式包括相当复杂的 2755 行 xhtml 模式 (http://www.w3.org/2002/08/xhtml/xhtml1-transitional.xsd)。即使对于非常简单的数据,这也需要很长时间(验证大约 30 秒)。因为我的批处理中有数千个 XML 文件,所以这并不能很好地扩展。
为了验证 XML 文件,我使用了标准 php-xml 库中的这两种方法。
我认为 PHP 实现通过 HTTP 获取 XHTML 模式并构建一些内部表示(可能是 DOMDocument),并且在验证完成时将其丢弃。我在想 XML-libs 的某些选项可能会改变这种行为,以便在此过程中缓存某些内容以供重用。
我构建了一个简单的测试设置来说明我的问题:
<xs:schema attributeFormDefault="unqualified"
elementFormDefault="qualified"
targetNamespace="http://myschema.example.com/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:myschema="http://myschema.example.com/"
xmlns:xhtml="http://www.w3.org/1999/xhtml">
<xs:import
schemaLocation="http://www.w3.org/2002/08/xhtml/xhtml1-transitional.xsd"
namespace="http://www.w3.org/1999/xhtml">
</xs:import>
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="MyHTMLElement">
<xs:complexType>
<xs:complexContent>
<xs:extension base="xhtml:Flow"></xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns="http://myschema.example.com/" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xml="http://www.w3.org/XML/1998/namespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://myschema.example.com/ test-schema.xsd ">
<MyHTMLElement>
<xhtml:p>This is an XHTML paragraph!</xhtml:p>
</MyHTMLElement>
</Root>
<?php
$data_dom = new DOMDocument();
$data_dom->load('test-data.xml');
// Multiple validations using the schemaValidate method.
for ($attempt = 1; $attempt <= 3; $attempt++) {
$start = time();
echo "schemaValidate: Attempt #$attempt returns ";
if (!$data_dom->schemaValidate('test-schema.xsd')) {
echo "Invalid!";
} else {
echo "Valid!";
}
$end = time();
echo " in " . ($end-$start) . " seconds.\n";
}
// Loading schema into a string.
$schema_source = file_get_contents('test-schema.xsd');
// Multiple validations using the schemaValidate method.
for ($attempt = 1; $attempt <= 3; $attempt++) {
$start = time();
echo "schemaValidateSource: Attempt #$attempt returns ";
if (!$data_dom->schemaValidateSource($schema_source)) {
echo "Invalid!";
} else {
echo "Valid!";
}
$end = time();
echo " in " . ($end-$start) . " seconds.\n";
}
运行这个 schematest.php 文件会产生以下输出:
schemaValidate: Attempt #1 returns Valid! in 30 seconds.
schemaValidate: Attempt #2 returns Valid! in 30 seconds.
schemaValidate: Attempt #3 returns Valid! in 30 seconds.
schemaValidateSource: Attempt #1 returns Valid! in 32 seconds.
schemaValidateSource: Attempt #2 returns Valid! in 30 seconds.
schemaValidateSource: Attempt #3 returns Valid! in 30 seconds.
非常欢迎任何有关如何解决此问题的帮助和建议!
最佳答案
您可以安全地从时间值中减去 30 秒作为开销。
对 W3C 服务器的远程请求被延迟,因为大多数库没有反射(reflect)缓存文档(甚至 HTTP header 也表明了这一点)。但是read your own :
The W3C servers are slow to return DTDs. Is the delay intentional?
Yes. Due to various software systems downloading DTDs from our site millions of times a day (despite the caching directives of our servers), we have started to serve DTDs and schema (DTD, XSD, ENT, MOD, etc.) from our site with an artificial delay. Our goals in doing so are to bring more attention to our ongoing issues with excessive DTD traffic, and to protect the stability and response time of the rest of our site. We recommend HTTP caching or catalog files to improve performance.
W3.org 试图将请求保持在较低水平。这是可以理解的。 PHP 的 DomDocument
基于 libxml。 libxml 允许设置外部实体加载器。整体Catalog support section在这种情况下很有趣。
要解决问题,设置一个 catalog.xml
文件:
<?xml version="1.0"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<system systemId="http://www.w3.org/2002/08/xhtml/xhtml1-transitional.xsd"
uri="xhtml1-transitional.xsd"/>
<system systemId="http://www.w3.org/2001/xml.xsd"
uri="xml.xsd"/>
</catalog>
保存两个 .xsd
文件的副本,并在目录旁边使用该目录文件中给出的名称(相对和绝对路径 file:///...
如果您喜欢不同的目录,请执行此操作)。
然后确保您的系统环境变量 XML_CATALOG_FILES
设置为 catalog.xml
文件的文件名。当一切都设置好后,验证将通过:
schemaValidate: Attempt #1 returns Valid! in 0 seconds.
schemaValidate: Attempt #2 returns Valid! in 0 seconds.
schemaValidate: Attempt #3 returns Valid! in 0 seconds.
schemaValidateSource: Attempt #1 returns Valid! in 0 seconds.
schemaValidateSource: Attempt #2 returns Valid! in 0 seconds.
schemaValidateSource: Attempt #3 returns Valid! in 0 seconds.
如果仍然需要很长时间,则表明环境变量没有设置到正确的位置。我在博客文章中也处理了变量和一些边缘情况:
它应该处理各种边缘情况,例如包含空格的文件名。
或者,可以创建一个简单的外部实体加载器回调函数,该函数使用 URL => 数组形式的本地文件系统的文件映射:
$mapping = [
'http://www.w3.org/2002/08/xhtml/xhtml1-transitional.xsd'
=> 'schema/xhtml1-transitional.xsd',
'http://www.w3.org/2001/xml.xsd'
=> 'schema/xml.xsd',
];
如图所示,我已将这两个 XSD 文件的逐字副本放入名为 schema
的子目录中。下一步是利用 libxml_set_external_entity_loader
使用映射激活回调函数。磁盘上已经存在的文件是首选并直接加载。如果例程遇到没有映射的非文件,将抛出 RuntimeException
并附有详细消息:
libxml_set_external_entity_loader(
function ($public, $system, $context) use ($mapping) {
if (is_file($system)) {
return $system;
}
if (isset($mapping[$system])) {
return __DIR__ . '/' . $mapping[$system];
}
$message = sprintf(
"Failed to load external entity: Public: %s; System: %s; Context: %s",
var_export($public, 1), var_export($system, 1),
strtr(var_export($context, 1), [" (\n " => '(', "\n " => '', "\n" => ''])
);
throw new RuntimeException($message);
}
);
设置此外部实体加载器后,远程请求不再有延迟。
就是这样。参见 Gist .注意:这个外部实体加载器是为加载 XML 文件而编写的,以从磁盘进行验证并将 XSD URI“解析”为本地文件名。其他类型的操作(例如基于 DTD 的验证)可能需要一些代码更改/扩展。更可取的是 XML 目录。它还适用于不同的工具。
关于php - 针对相同的 XML 模式 (XSD) 加速一批 XML 文件的 XML 模式验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13865149/
在 JSF2 应用程序中遇到验证属性的问题时,有两种主要方法。 使用 Annotation 在 ManagedBean 上定义验证 @ManagedBean public class MyBean {
我想实现一个不常见的功能,我认为 jquery 验证插件将是最好的方法(如果您在没有插件的情况下建议和回答,我们也会欢迎)。我想在用户在输入字段中输入正确的单词后立即隐藏表单。我试过这个: $("
我有几个下拉菜单(类名为month_dropdown),并且下拉菜单的数量不是恒定的。我怎样才能为它们实现 NotEqual 验证。我正在使用 jQuery 验证插件。 这就是我写的 - jQuery
我设法制作了这个网址验证代码并且它起作用了。但我面临着一个问题。我认为 stackoverflow 是获得解决方案的最佳场所。 function url_followers(){ var url=do
我目前正在使用后端服务,该服务允许用户在客户端应用程序上使用 Google Games 库登录。 用户可以通过他们的 gplay ID 向我们发送信息,以便登录或恢复旧帐户。用户向我们发送以下内容,包
我正在尝试验证输入以查看它是否是有效的 IP 地址(可能是部分地址)。 可接受的输入:172、172.112、172.112.113、172.112.113.114 Not Acceptable 输入
我从 Mongoose 验证中得到这条消息: 'Validator failed for path phone with value ``' 这不应该发生,因为不需要电话。 这是我的模型架构: var
我一直在尝试使用Python-LDAP (版本 2.4.19)在 MacOS X 10.9.5 和 Python 2.7.9 下 我想在调用 .start_tls_s() 后验证与给定 LDAP 服务
我正在处理一个仅与 IE6 兼容的旧 javascript 项目(抱歉...),我想仅在 VS 2017 中禁用此项目的 ESLint/CSLint/Javascript 验证/CSS 验证。 我知道
我正在寻找一种方法来验证 Spring 命令 bean 中的 java.lang.Double 字段的最大值和最小值(一个值必须位于给定的值范围之间),例如, public final class W
我正在尝试在 springfuse(JavaEE 6 + Spring Framework (针对 Jetty、Tomcat、JBoss 等)) 和 maven 的帮助下构建我的 webapps 工作
我试图在我们的项目中使用 scalaz 验证,但遇到了以下情况: def rate(username: String, params: Map[String, String]): Validation
我有一个像这样的 Yaml 文件 name: hhh_aaa_bbb arguments: - !argument name: inputsss des
我有一个表单,人们可以单击并向表单添加字段,并且我需要让它在单击时验证这些字段中的值。 假设我单击它两次并获取 2 个独立的字段集,我需要旋转 % 以确保它在保存时等于 100。 我已放入此函数以使其
在我的页面中有一个选项可以创建新的日期字段输入框。用户可以根据需要创建尽可能多的“截止日期”和“起始日期”框。就像, 日期_to1 || date_from1 日期到2 ||日期_from2 date
我有一个像这样的 Yaml 文件 name: hhh_aaa_bbb arguments: - !argument name: inputsss des
有没有办法在动态字段上使用 jquery 验证表单。 我想将其设置为必填字段 我正在使用 Jsp 动态创建表单字段。 喜欢 等等...... 我想使用必需的表单字段验证此表单字段。 最佳答
嗨,任何人都可以通过提供 JavaScript 代码来帮助我验证用户名文本框不应包含数字,它只能包含一个字符。 最佳答案 使用正则表达式: (\d)+ 如果找到匹配项,则字符串中就有一个数字。 关于J
我有两个输入字段holidayDate和Description(id=tags) $(document).ready(function() {
我遇到了这个问题,这些验证从电子邮件验证部分开始就停止工作。 我只是不明白为什么即使经过几天的观察,只是想知道是否有人可以在这里指出我的错误? Javascript部分: function valid
我是一名优秀的程序员,十分优秀!