[英]Xml validation against xml schema fails in php but works in .NET (VS2010)
我有幾個xml文件,但是我只給出一個文件和用於驗證它的xsd文件。 首先讓我描述一下問題。 我在VS2010中編輯文件,而VS運行時解析器在編輯xml文件時未顯示任何錯誤。 然后,當我運行一個php命令行腳本,該腳本加載xml文件並針對xml架構對其進行驗證時,它的結尾是一個例外,說
警告:DOMDocument :: schemaValidate():元素'element':未找到keyref'elementRef'的鍵序列['answers']匹配項。
但是,我真的看不到xsd文件中的錯誤。
xml文件:
<domain xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Answer" namespace="Custom\Surveys" xsi:noNamespaceSchemaLocation="../../xsd/domain.xsd">
<entities>
<entity name="Answer" main="true" schema="answers"/>
</entities>
<bindings>
</bindings>
<key>
<element entity="answers" property="question_option_id"/>
<element entity="answers" property="survey_voter_id"/>
</key>
</domain>
xsd文件中的XML模式:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="domain">
<xs:complexType>
<xs:sequence>
<xs:element name="entities">
<xs:complexType>
<xs:sequence>
<xs:element name="entity" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" id="entityName" />
<xs:attribute name="main" type="xs:boolean" use="optional" default="false" />
<xs:attribute name="schema" type="xs:string" use="required" id="schemaName" />
</xs:complexType>
</xs:element>
<xs:element name="multientity" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="schema" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="bindings" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="bind" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="referenced">
<xs:complexType>
<xs:attribute name="entity" type="xs:string" use="required" />
<xs:attribute name="property" type="xs:string" use="required" />
</xs:complexType>
<xs:keyref name="referencedRef" refer="entityId">
<xs:selector xpath="." />
<xs:field xpath="@entity" />
</xs:keyref>
</xs:element>
</xs:sequence>
<xs:attribute name="entity" type="xs:string" use="required" />
<xs:attribute name="property" type="xs:string" use="required" />
</xs:complexType>
<xs:keyref name="bindRef" refer="entityId">
<xs:selector xpath="." />
<xs:field xpath="@entity" />
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="key">
<xs:complexType>
<xs:sequence>
<xs:element name="element" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="entity" type="xs:string" use="required" />
<xs:attribute name="property" type="xs:string" use="required" />
</xs:complexType>
<xs:keyref name="elementRef" refer="entityId">
<xs:selector xpath="." />
<xs:field xpath="@entity" />
</xs:keyref>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="namespace" type="xs:string" use="required" />
</xs:complexType>
<xs:key name="entityId">
<xs:selector xpath="./entities/entity|./entities/multientity" />
<xs:field xpath="@schema" />
</xs:key>
</xs:element>
</xs:schema>
我找到了一個解決方案,我必須在根元素的最后定義所有鍵和keyref。
這是新的xsd文件:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="domain">
<xs:complexType>
<xs:sequence>
<xs:element name="entities">
<xs:complexType>
<xs:sequence>
<xs:element name="entity" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" id="entityName" />
<xs:attribute name="main" type="xs:boolean" use="optional" default="false" />
<xs:attribute name="schema" type="xs:string" use="required" id="schemaName" />
</xs:complexType>
</xs:element>
<xs:element name="multientity" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="schema" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="bindings" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:element name="bind" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="referenced">
<xs:complexType>
<xs:attribute name="entity" type="xs:string" use="required" />
<xs:attribute name="property" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="entity" type="xs:string" use="required" />
<xs:attribute name="property" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="key">
<xs:complexType>
<xs:sequence>
<xs:element name="element" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="entity" type="xs:string" use="required" />
<xs:attribute name="property" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required" />
<xs:attribute name="namespace" type="xs:string" use="required" />
</xs:complexType>
<xs:key name="entityId">
<xs:selector xpath="./entities/entity|./entities/multientity" />
<xs:field xpath="@schema" />
</xs:key>
<xs:keyref name="elementRef" refer="entityId">
<xs:selector xpath="./key/element" />
<xs:field xpath="@entity" />
</xs:keyref>
<xs:keyref name="bindRef" refer="entityId">
<xs:selector xpath="./bindings/bind" />
<xs:field xpath="@entity" />
</xs:keyref>
<xs:keyref name="referencedRef" refer="entityId">
<xs:selector xpath="./bindings/bind/referenced" />
<xs:field xpath="@entity" />
</xs:keyref>
</xs:element>
</xs:schema>
如果可能的話,我建議始終將keyref及其對應的密鑰放在同一級別(在同一元素聲明中)。 從理論上講,它不是必需的,但是當您不做這些規則時,它們會變得異常復雜,有時甚至違反直覺。 (我之所以不告訴您規則是什么,是因為我知道閱讀該領域的規范會傷害我的大腦,如果不閱讀該規范,我將無法記住規則。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.