php - 元素 'foo' : This element is not expected. 预期为 ( {http ://www. example.com}foo )

标签 php xml validation schema domdocument

当尝试使用 schemaValidate 方法根据模式验证 PHP DOMDocument 对象时,将生成下一个警告:

Warning: DOMDocument::schemaValidate(): Element 'foo': This element is not expected. Expected is ( {http://www.example.com}foo ). in X on line Y

它只发生在附加到 DOMDocument 的元素上。我准备了下一个代码片段和架构,以便任何人都可以立即进行测试:

片段:

$template = '
    <root
        xmlns="http://www.example.com"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.example.com schema.xsd"
    >
        <bar/>
    </root>
';

$DD = new DOMDocument(); 
$DD -> loadXML($template);
$foo = $DD -> createElement('foo');
$DD -> getElementsByTagName('root') -> item(0) -> appendChild($foo);
var_dump(htmlentities($DD -> saveXML()));
var_dump($DD -> schemaValidate(__DIR__ . '/schema.xsd'));

架构:

<?xml version="1.0"?>
<xs:schema
    targetNamespace="http://www.example.com"
    xmlns:SiiDte="http://www.example.com"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified"
>
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="bar"/>
                <xs:element name="foo"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

我看不出 foo 和 bar 之间的区别,foo 是用 appendChild 方法添加的,而 bar 是用 loadXML 方法添加的。

验证返回 false(这意味着验证错误)。当使用 loadXML 方法加载 foo 时,错误停止发生,但这绝对不是解决方案,因为在很多情况下需要动态创建 XML。

¿为什么附加元素会产生此验证错误以及如何解决?

最佳答案

您创建的元素 <foo> “缺少”命名空间,因此在空命名空间中。

命名空间也是您在错误消息中的大括号(或尖括号)中看到的部分:

  {http://www.example.com}foo
  `----------------------´`-´
           namespace      name

使用 createElement 代替 createElementNS 并在元素名称旁边提供命名空间。

当您将创建的文档保存为 XML(例如通过查看手动验证它)时,您完全正确地认为该元素似乎类似于 <bar> :

<?xml version="1.0"?>
<root xmlns="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com schema.xsd">
    <bar/>
<foo/></root>

但是它刚刚被添加到那里,它是 null namspace(因此插入时周围没有太多命名空间)并且在内存中元素仍然没有命名空间 - 并且验证在内存中。

这是一个完整的验证示例:

<?php
/**
 * Element 'foo': This element is not expected. Expected is ( {http://www.example.com}foo )
 *
 * @link http://stackoverflow.com/a/29925747/367456
 */

$template = <<<XML
<root
    xmlns="http://www.example.com"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.example.com schema.xsd">
    <bar/>
</root>
XML;

$schema = <<<XML
<?xml version="1.0"?>
<xs:schema
    targetNamespace="http://www.example.com"
    xmlns:SiiDte="http://www.example.com"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified"
    attributeFormDefault="unqualified">
    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="bar"/>
                <xs:element name="foo"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>
XML;
$schema = 'data://text/xml;base64,' . base64_encode($schema);

$namespace = 'http://www.example.com';

$doc = new DOMDocument();
$doc->loadXML($template);
$foo = $doc->createElementNS($namespace, 'foo');
$doc->documentElement->appendChild($foo);
echo $doc->saveXML();

var_dump($doc->schemaValidate($schema));

输出是:

<?xml version="1.0"?>
<root xmlns="http://www.example.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com schema.xsd">
    <bar/>
<foo/></root>
bool(true)

关于php - 元素 'foo' : This element is not expected. 预期为 ( {http ://www. example.com}foo ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29924308/

相关文章:

javascript - URI 正则表达式 : Replace http://, https ://, ftp://如果 URL 有效则为空字符串

php - 过滤掉所有与四个不同元素中的多个规则不匹配的行

php - 简单的子查询?

PHP SQL 日期时间问题

php - RSS Feed 无法工作 : something wrong with <? xml 版本 ="1.0"编码 ="iso-8859-1"?>

angularjs - 设置 $invalid 和 $error 不会使表单无效

php - Joomla 3.8 与 PHP 7 问题

android - 使用 setOnClickListener 并获取“Potential NullPointerException。某些布局版本中缺少资源”

python - 适合初学者的 OpenERP 报告创建

javascript - jQuery 验证——不验证