【问题标题】:XML validation with XSD使用 XSD 进行 XML 验证
【发布时间】:2012-04-13 13:15:12
【问题描述】:

我有我正在尝试验证的产品的 XML。

(我把它保存在 xml.xml 文件中)

<?xml version="1.0" encoding="UTF-8"?>
<catalog label="global">
    <catalog label="animals" link="/animals.php">
    <subject>Subject1</subject>
     </catalog>
    <catalog label="animals" link="/animals.php">
    <subject>Subject2</subject>
     </catalog>
</catalog>

使用this tool 生成XSD:(我放入文件xml.xsd)

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="catalog" type="catalogType" />
  <xsd:complexType name="catalogType">
    <xsd:sequence>
      <xsd:element maxOccurs="unbounded" name="catalog" type="catalogType" />
    </xsd:sequence>
    <xsd:attribute name="label" type="xsd:string" />
  </xsd:complexType>
  <xsd:complexType name="catalogType">
    <xsd:sequence>
      <xsd:element name="subject" type="xsd:string" />
    </xsd:sequence>
    <xsd:attribute name="label" type="xsd:string" />
    <xsd:attribute name="link" type="xsd:string" />
  </xsd:complexType>
</xsd:schema>

以及我用来测试它们的 PHP 代码(在 php.php 文件中):

<?php 

function libxml_display_error($error) 
{ 
  $return = "<br/>\n"; 
  switch ($error->level) { 
  case LIBXML_ERR_WARNING: 
  $return .= "<b>Warning $error->code</b>: "; 
  break; 
  case LIBXML_ERR_ERROR: 
  $return .= "<b>Error $error->code</b>: "; 
  break; 
  case LIBXML_ERR_FATAL: 
  $return .= "<b>Fatal Error $error->code</b>: "; 
  break; 
  } 
  $return .= trim($error->message); 
  if ($error->file) { 
  $return .= " in <b>$error->file</b>"; 
  } 
  $return .= " on line <b>$error->line</b>\n"; 

  return $return; 
} 

    function checkXMLStructure($xml_object)
    {
        $xmlElement = $xml_object->catalog;
        $dom_sxe = dom_import_simplexml($xmlElement);

        $dom = new DOMDocument('1.0');
        $dom_sxe = $dom->importNode($dom_sxe, true);
        $dom_sxe = $dom->appendChild($dom_sxe);

        if ( !$dom->schemaValidate( dirname(__FILE__) . '/xml.xsd') ) {
            echo "BAD XML\n";
        return;
        }

        echo "*GOOD* XML!\n";
    }

// Enable user error handling 
libxml_use_internal_errors(true);

$xml_object = simplexml_load_file('xml.xml');
checkXMLStructure($xml_object);

// Display Errors
$errors = libxml_get_errors(); 
foreach ($errors as $error) { 
print libxml_display_error($error); 
} 
libxml_clear_errors();

输出:

PHP Warning:  DOMDocument::schemaValidate(): Element '{http://www.w3.org/2001/XMLSchema}complexType': A global complex type definition 'catalogType' does already exist. in /path/php.php on line 13
PHP Stack trace:
PHP   1. {main}() /path/php.php:0
PHP   2. checkXMLStructure() /path/php.php:23
PHP   3. DOMDocument->schemaValidate() /path/php.php:13
PHP Warning:  DOMDocument::schemaValidate(): Invalid Schema in /path/php.php on line 13
PHP Stack trace:
PHP   1. {main}() /path/php.php:0
PHP   2. checkXMLStructure() /path/php.php:23
PHP   3. DOMDocument->schemaValidate() /path/php.php:13
BAD XML

我需要重写架构,以便它会注意到主元素内的 *many 元素(请注意相同的名称用法)。

【问题讨论】:

  • 抱歉,已在问题中更新。
  • 还是不知道是什么问题

标签: php xml validation xsd


【解决方案1】:

我已经使用QTAssistant 生成了下面的架构(它验证了您提供的 XML):

<?xml version="1.0" encoding="utf-8"?>
<!--W3C Schema generated by QTAssistant/W3C Schema Refactoring Module (http://www.paschidev.com)-->
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="catalog">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element maxOccurs="unbounded" name="catalog">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="subject" type="xsd:string" />
            </xsd:sequence>
            <xsd:attribute name="label" type="xsd:string" use="required" />
            <xsd:attribute name="link" type="xsd:string" use="required" />
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
      <xsd:attribute name="label" type="xsd:string" use="required" />
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

您可以从上面开始,并在进行过程中对其进行调整。

验证结果:

如果您希望手动修复您的工具创建的 XSD,请确保将 前两次出现的 catalogType 重命名为其他名称(例如 catalogType1)。 p>

【讨论】:

  • 感谢 xsd 朋友,但使用上面的 php 代码运行仍然会产生错误:php php.php BAD XML
    错误 1866: Element 'catalog', attribute 'link':不允许使用属性'link'。第 3
    错误 1871:元素“主题”:不需要此元素。预期是(目录)。在 4
  • 嗨@valk,我附上了您发布的XML 和我生成的XSD 的屏幕截图;验证在输出面板中显示为 OK。您一定有其他问题(可能是您正在使用的 XML?)...您确定您刚刚尝试的 XML 与发布的 XML 相同吗?我想不出别的了:(...
  • 嗯,我很确定。现在我重新检查了它。可能是 $dom->schemaValidate() 有一些错误,但我对此表示怀疑。顺便说一句,它是 PHP 5.3,但它不应该有所作为。
  • @valk,至少现在已经加载了模式;但是,该消息没有意义;您正在以某种方式验证嵌套的 catalog 节点而不是根节点 - 这是肯定的。看一下代码,因为您不是在验证根目录,而是下一个。神奇之处在于 $xml_object->catalog;尝试验证您的 $xml_object。
猜你喜欢
  • 2014-03-27
  • 2016-10-18
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2013-10-30
  • 2013-10-25
  • 1970-01-01
相关资源
最近更新 更多