【问题标题】:XML, XSD xs:keyref within recursive complex type defintion递归复杂类型定义中的 XML、XSD xs:keyref
【发布时间】:2012-08-06 15:07:10
【问题描述】:

我有一些 xml 数据,顶部有一个允许的类型列表,还有一个递归列表类型的对象和引用允许类型的子对象:

<?xml version="1.0" encoding="UTF-8"?>
<ROOT xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="KEYREF_TEST.xsd">
  <ALLOWED_SHAPE_TYPES>
    <SHAPE_TYPE>Circle</SHAPE_TYPE>
    <SHAPE_TYPE>Triangle</SHAPE_TYPE>
    <SHAPE_TYPE>Square</SHAPE_TYPE>
  </ALLOWED_SHAPE_TYPES>
  <SHAPES>
    <SHAPE>
      <TYPE>Triangle</TYPE>
      <SUB_SHAPES>
        <SHAPE>
          <TYPE>Circle</TYPE>
          <SUB_SHAPES/>
        </SHAPE>
        <SHAPE>
          <TYPE>Square</TYPE>
          <SUB_SHAPES>
            <SHAPE>
              <TYPE>Triangle</TYPE>
              <SUB_SHAPES/>
            </SHAPE>
          </SUB_SHAPES>
        </SHAPE>
      </SUB_SHAPES>
    </SHAPE>
    <SHAPE>
      <TYPE>Square</TYPE>
      <SUB_SHAPES/>
    </SHAPE>
  </SHAPES>
</ROOT>

我已定义验证此文档的架构如下:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="ROOT">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ALLOWED_SHAPE_TYPES">
          <xs:complexType>
            <xs:sequence minOccurs="0" maxOccurs="unbounded">
              <xs:element name="SHAPE_TYPE" type="xs:string"/>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="SHAPES" type="shape-list-type"/>
      </xs:sequence>
    </xs:complexType>
    <xs:unique name="SHAPE_TYPE_UK">
      <xs:selector xpath="ALLOWED_SHAPE_TYPES/SHAPE_TYPE"/>
      <xs:field xpath="."/>
    </xs:unique>
  </xs:element>
  <xs:complexType name="shape-list-type">
    <xs:sequence>
      <xs:element name="SHAPE" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
         <xs:sequence>
            <xs:element name="TYPE" type="xs:string">
              <xs:keyref name="SHAPE_TYPE_FK" refer="SHAPE_TYPE_UK">
                <xs:selector xpath="."></xs:selector>
                <xs:field xpath="."></xs:field>
              </xs:keyref>
            </xs:element>
            <xs:element name="SUB_SHAPES" type="shape-list-type"/>
          </xs:sequence>
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

在 oXygen 13.2 中验证时出现以下错误:

System ID: C:\pvcswork\CodeSource\XMLSchema\KEYREF_DATA.xml
Main validation file: C:\pvcswork\CodeSource\XMLSchema\KEYREF_DATA.xml
Schema: C:\pvcswork\CodeSource\XMLSchema\KEYREF_TEST.xsd
Engine name: Xerces
Severity: error
Description: Identity Constraint error:  identity constraint "KeyRef@1df2ead" has a keyref which refers to a key or unique that is out of scope.
Start location: 10:28

我相信这是因为 xs:keyref 是 xs:complexType 定义的子元素,它不是定义 xs:unique 的 xs:element 的子元素。

我可以将 xs:keyref 移动到 ROOT 定义中并使用 XPath 定位 TYPE 元素,但是 // 语法是不允许的,所以我会失去递归并且必须为每个级别定义一个新的 xs:keyref嵌套。 ** UPDATE - // 在 XPath 开始时允许,前面有一个点! **

是否有我错过的解决方案(仍在使用 XSD)?提前谢谢..

【问题讨论】:

    标签: xml recursion xsd xerces keyref


    【解决方案1】:

    下面的 XSD 将是我对您的问题的解决方案。我基本上修复了一些选择器并将它们放在同一级别。

    XSD:

    <?xml version="1.0" encoding="UTF-8"?> 
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
        <xs:element name="ROOT"> 
            <xs:complexType> 
                <xs:sequence> 
                    <xs:element name="ALLOWED_SHAPE_TYPES"> 
                        <xs:complexType> 
                            <xs:sequence minOccurs="0" maxOccurs="unbounded"> 
                                <xs:element name="SHAPE_TYPE" type="xs:string"/> 
                            </xs:sequence> 
                        </xs:complexType> 
                    </xs:element> 
                    <xs:element name="SHAPES" type="shape-list-type"/> 
                </xs:sequence> 
            </xs:complexType> 
            <xs:unique name="SHAPE_TYPE_UK"> 
                <xs:selector xpath="ALLOWED_SHAPE_TYPES/SHAPE_TYPE"/> 
                <xs:field xpath="."/> 
            </xs:unique> 
            <xs:keyref name="SHAPE_TYPE_FK" refer="SHAPE_TYPE_UK"> 
                <xs:selector xpath=".//SHAPE/TYPE"></xs:selector> 
                <xs:field xpath="."></xs:field> 
            </xs:keyref>        
        </xs:element> 
        <xs:complexType name="shape-list-type"> 
            <xs:sequence> 
                <xs:element name="SHAPE" minOccurs="0" maxOccurs="unbounded"> 
                    <xs:complexType> 
                        <xs:sequence> 
                            <xs:element name="TYPE" type="xs:string"/> 
                            <xs:element name="SUB_SHAPES" type="shape-list-type"/> 
                        </xs:sequence> 
                    </xs:complexType> 
                </xs:element> 
            </xs:sequence> 
        </xs:complexType> 
    </xs:schema> 
    

    【讨论】:

    • 谢谢,老实说,我以为我已经尝试过了,设法说服自己在 XSD 中不允许使用“//”。这个溶胶虽然有效。
    • 原来 '//' 是允许的,但只能在 XPath 的开头并以 '.' 开头。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 2017-07-26
    • 1970-01-01
    • 2017-11-20
    • 1970-01-01
    相关资源
    最近更新 更多