PHP - 带有 unicode 正则表达式的 XSD 模式验证错误

Posted

技术标签:

【中文标题】PHP - 带有 unicode 正则表达式的 XSD 模式验证错误【英文标题】:PHP - XSD schema validation error with unicode regular expression 【发布时间】:2012-02-12 02:12:11 【问题描述】:

说明:

当我尝试使用包含 Unicode 常规的给定 XSD 架构验证 XML 文件时 表达式,函数 DOMDocument::schemaValidate 返回一个验证错误。 XSD 模式是 W3C 格式良好的,并且验证通过了另一个 验证工具。 如果 XSD 模式是这样的格式(没有正方形 括号):

<xsd:pattern value="\PLl+"/>

php 版本:5.2.14 LibXml 版本:2.7.7

之前的模式[\PLl]+preg_match 函数一起正常工作。


测试脚本:

PHP 验证码:

function libxml_display_errors()

   $errors = libxml_get_errors();

   print_r($errors);

   libxml_clear_errors();


libxml_use_internal_errors(true);

$dom = new DOMDocument();
$dom->load('test.xml');

if ( !$dom->schemaValidate('test.xsd') ) 
  echo "XML Error\n";
  libxml_display_errors();
 else 
  echo "XML ok\n";


XSD 架构:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xsd:simpleType name="noLowerCase">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="[\PLl]+"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:complexType name="DatiUtenteType">
        <xsd:sequence>
            <xsd:element name="Cognome" type="noLowerCase"/>
            <xsd:element name="Nome" type="noLowerCase"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:complexType name="DataExchangeFisso">
        <xsd:sequence>
            <xsd:element name="DatiUtente" type="DatiUtenteType"/>
        </xsd:sequence>
    </xsd:complexType>
    <xsd:element name="ListOfDataExchange">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="DataExchangeFisso" type="DataExchangeFisso" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<ListOfDataExchange>
  <DataExchangeFisso>
    <DatiUtente>
      <Cognome>FOO</Cognome>
      <Nome>BAR</Nome>
    </DatiUtente>
  </DataExchangeFisso>
</ListOfDataExchange>

预期结果:

XML ok

实际结果:

XML Error
Array
(
    [0] => LibXMLError Object
        (
            [level] => 2
            [code] => 1839
            [column] => 0
            [message] => Element 'Cognome': [facet 'pattern'] The value 'FOO' is not accepted by the pattern '[\PLl]+'.
            [file] => /var/www/html/test.xml
            [line] => 5
        )

    [1] => LibXMLError Object
        (
            [level] => 2
            [code] => 1824
            [column] => 0
            [message] => Element 'Cognome': 'FOO' is not a valid value of the atomic type 'noLowerCase'.
            [file] => /var/www/html/test.xml
            [line] => 5
        )

    [2] => LibXMLError Object
        (
            [level] => 2
            [code] => 1839
            [column] => 0
            [message] => Element 'Nome': [facet 'pattern'] The value 'BAR' is not accepted by the pattern '[\PLl]+'.
            [file] => /var/www/html/test.xml
            [line] => 6
        )

    [3] => LibXMLError Object
        (
            [level] => 2
            [code] => 1824
            [column] => 0
            [message] => Element 'Nome': 'BAR' is not a valid value of the atomic type 'noLowerCase'.
            [file] => /var/www/html/test.xml
            [line] => 6
        )
)

【问题讨论】:

【参考方案1】:

这不是您问题的完整答案,但可能是一些澄清:

XSD 中的正则表达式,即使它可能与preg_match 中的正则表达式相似,也是不同的东西。因此,假设某些东西必须与 XSD 一起使用,因为它确实与 preg_match 一起使用是一种猜测,但不是严格的测试。

categoryDocs 小写字母及其属性 Ll 由 Unicode 定义,XSD 库应该支持它。

可能是类别的否定性有问题,因为它只说非否定字符类中的什么,而不是什么。

试试:

[^\pLl]+

【讨论】:

给了我 XSD 模式验证。我无法更改它,否则我将足以删除方括号。 那么你需要修复库组件。我认为它应该按规范工作,因此该库已损坏并需要修复。它是免费软件,您可以对其进行修补并将修复程序带入新版本。 那么你认为这是一个 php 错误吗?我尝试在php网站上报告它,但我还没有收到任何回复。 我无法判断是bug还是功能。但是,这肯定不是 PHP,而是底层库(可能是 XSLT)。您也应该在此处留下一个指向您的错误报告的链接以及您的问题。【参考方案2】:

架构很好,您的架构处理器有错误或不符合项。实际上,模式处理器实现正则表达式方言与 XSD 规范中定义的方言有些不同的情况并不罕见:惰性实现者只是将正则表达式直接传递给他们选择的库。

【讨论】:

问题是其他验证器(例如 Notepad++ XML 工具)的验证也会失败,但根据 w3c 规范在形式上是正确的。

以上是关于PHP - 带有 unicode 正则表达式的 XSD 模式验证错误的主要内容,如果未能解决你的问题,请参考以下文章

带有 unicode 和标点符号的 Javascript 正则表达式

带有 unicode 字符的 Python 正则表达式错误?

Python 和带有 Unicode 的正则表达式

Unicode 正则表达式;无效的 XML 字符

查找正则表达式匹配 x 的数量,将数据帧的某些列重复 x 次 + Unicode 错误

php 正则表达式