簡體   English   中英

當我有多個架構文檔時如何使用 php 驗證 xml

[英]how to validate xml with php when I have multiple schema documents

我已經知道如何使用 php 程序驗證單個 xsd,當我按照本教程https://www.tutorialspoint.com/xsd/xsd_complex_any.htm 進行操作時,xsd 驗證中的<xs:any>標簽仍然存在問題,以下是我的演示:

人.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>

和我的孩子.xsd

<?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>

我的 test.xml 文件如下:

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

單個驗證 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 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(); 
}


?>

現在我的問題是如何使用 person.xsd 和 child.xsd 驗證 test.xml 。 你能給我一些建議嗎?

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

感謝 CM Sperberg-McQueen 給我一些提示來創建另一個名為 driver.xsd 的文件來解決我的問題

以下是我的解決方案:

驅動程序.xsd

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

和我的 test.xml

<?xml version="1.0" encoding="UTF-8"?>

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

現在我可以使用相同的 php 驗證程序通過多個 xsd 驗證我的 xml

非常感謝

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

如果我理解正確,您的問題相當於:如何讓我的 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"到通配符。

首先,xml 必須具有所有 xsd 所需文件的 schemaLocation。 我們需要讀取 xml 並檢測所有 xsd 所需的文件。 使用唯一的 xsd(主要或第一個)驗證 XML,但將其余的所需 xsd 導入其中(基本 xsd)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM