当我有多个架构文档时,如何用php验证xml

时间:2017-09-14 10:36:01

标签: php xml xsd

我已经知道如何使用php程序验证单个xsd,当我按照本教程https://www.tutorialspoint.com/xsd/xsd_complex_any.htm时,我仍然在xsd验证中遇到time = data.get(0)[0];标签问题,以下是我的演示:< / p>

person.xsd

<xs:any>

和我的child.xsd

<?xml version="1.0" encoding="UTF-8"?>
    <xs:schema 
    xmlns="http://cos-git.dev"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    targetNamespace="http://cos-git.dev"
    elementFormDefault="qualified">

    <xs:element name="persons">
      <xs:complexType>
        <xs:sequence>
          <xs:element name="person" maxOccurs="unbounded">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="full_name" type="xs:string"/>
                <xs:element name="child_name" type="xs:string" minOccurs="0" maxOccurs="5"/>
                <xs:any minOccurs = "0"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:sequence>
      </xs:complexType>
    </xs:element>

    </xs:schema>

我的test.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
    <xs:schema 
        xmlns="http://www.w3school.com.cn"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.w3school.com.cn"
        elementFormDefault="qualified">

        <xs:element name="children">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="childname" type="xs:string"
              maxOccurs="unbounded"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
    </xs:schema>

单一验证php程序如下:

 <persons xmlns="http://cos-git.dev" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://cos-git.dev person.xsd http://www.w3school.com.cn child.xsd">
    <person>
        <full_name>Tony Smith</full_name>
        <child_name>Cecilie</child_name>
        <children>
            <childname>Name</childname>
        </children> 
    </person>
</persons>

现在我的问题是如何使用person.xsd和child.xsd验证test.xml。你能给我一些提示吗?

==============

感谢C. M. Sperberg-McQueen给我一些提示来创建另一个名为driver.xsd的文件以解决我的问题

以下是我的解决方案:

driver.xsd

<?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 libxml_display_errors() { 
    $errors = libxml_get_errors(); 
    var_dump($errors);exit;
    foreach ($errors as $error) { 
        print libxml_display_error($error); 
    } 
    libxml_clear_errors(); 
} 

// Enable user error handling 
libxml_use_internal_errors(true); 

$xml = new DOMDocument(); 
$xml->load('xmlfilepath'); 

if ($xml->schemaValidate('xsdfilename')) {
    echo "validated</n>"; 

}else{
    libxml_display_errors(); 
}


?>

和我的test.xml

<xs:schema  xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://cos-git.dev" schemaLocation="person.xsd"/>
<xs:import namespace="http://www.w3school.com.cn" schemaLocation="child.xsd"/>
</xs:schema>

现在我可以使用相同的php验证程序

通过几个xsd验证我的xml

非常感谢

如果您有其他解决方案,请分享您的想法:)

2 个答案:

答案 0 :(得分:1)

如果我理解正确,你的问题相当于:如何让我的XSD验证器加载(并构建一个架构)person.xsd和child.xsd?答案原则上取决于您的验证人;检查其文档。许多验证器允许您在调用它们时指定多个模式文档。

如果找不到可以回答问题的架构验证程序的文档,或者验证程序在运行时只愿意接受单个架构文档(或URI),那么最简单的方法就是制作一个名为driver.xsd的模式文档,其内容将是这样的(未经测试):

<xsd:schema ...>
  <xsd:import namespace="http://cos-git.dev"
    schemaLocation=".../person.xsd"/>
  <xsd:import namespace="http://www.w3school.com.cn"
    schemaLocation=".../child.xsd"/>
</xsd:schema>

当您对driver.xsd架构文档进行验证时,您将被告知'person'的复杂类型是不确定的:因为您的通配符与'child_name'元素匹配,输入中的'child_name'元素可以匹配该名称的本地元素或该名称的未声明的全局元素。解析器不愿意猜测是什么意思。修复该问题的最简单方法是将namespace="##other"添加到通配符。

答案 1 :(得分:0)

我对此有一个想法,我正在努力中。 首先,xml必须具有所有xsd必需文件的schemaLocation。 我们需要阅读xml并检测所有xsd必需的文件。 使用唯一的xsd(主要或第一个)验证XML,但将其余所需的xsd导入XML(基本xsd)。 我使用C#解决了这个问题,但是现在我也需要PHP。