【问题标题】:Xml validation against xml schema fails in php but works in .NET (VS2010)针对 xml 模式的 XML 验证在 php 中失败,但在 .NET (VS2010) 中有效
【发布时间】:2023-03-04 04:01:01
【问题描述】:

我有几个 xml 文件,但我只会展示一个和我验证它的 xsd。让我首先描述一下这个问题。我在 VS2010 中编辑文件,VS 运行时解析器在编辑 xml 文件时没有显示错误。然后,当我运行一个加载 xml 文件并根据 xml 模式验证它的 php 命令行脚本时,它以一个 excption 结束,说

警告: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>

【问题讨论】:

  • 您是否在 XML 文件中添加了正确的标题? &lt;?xml version="1.0" encoding="utf-8"?&gt;

标签: php xml xsd primary-key keyref


【解决方案1】:

我找到了解决方案,我必须在最后定义根元素中的所有键和 keyrefs。

这是新的 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>

【讨论】:

    【解决方案2】:

    如果可能的话,我建议始终将 keyref 及其对应的键放在同一级别(在同一元素声明中)。这在理论上不是必需的,但是当你不需要时的规则非常复杂,有时甚至违反直觉。 (我不告诉你规则是什么的原因是我知道阅读这方面的规范会伤害我的大脑,如果不阅读规范我可能无法记住规则。)

    【讨论】:

    • 我知道我已尝试阅读规则。我完全按照你说的做了(即我自己的回答)。
    猜你喜欢
    • 2014-10-20
    • 2011-05-15
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多