元素'foo':不期望这个元素。预计是({http://www.example.com} foo)

时间:2015-04-28 16:00:19

标签: php xml validation schema domdocument

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

  

警告:DOMDocument :: schemaValidate():元素'foo':此元素是   没想到。预计是({http://www.example.com} foo)。在X上   Y行

仅在已附加到DOMDocument的元素上发生。我准备了下一个代码片段和模式,以便任何人都可以立即测试:

段:

 function user_exists($username) {
    $username = sanitize($username);
    $result=mysql_result(mysql_query("SELECT COUNT(customerNumber) FROM customers WHERE username = '$username'"), 0);
    print $result; //see what it returns
    die();  //remove this line after your debugging.
    return ($result == 1) ? true : false;
}

架构:

$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'));

我没有看到foo和bar之间的区别除了foo之外添加了appendChild方法,而bar添加了loadXML方法。

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

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

1 个答案:

答案 0 :(得分:1)

您创建的元素<foo>是&#34;缺少&#34;命名空间,因此在null命名空间中。

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

  {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)