【问题标题】:Are circular groups allowed by XSD schema?XSD 模式是否允许循环组?
【发布时间】:2010-10-29 04:18:48
【问题描述】:

对于这个xml:

<elem1 xmlns="http://www.fixprotocol.org/ns/fast/t/1.0">
 <elem2>
   <elem2/>
 </elem2>
</elem1>

我有这个架构,它似乎可以很好地针对w3 schema validation service 进行验证,并且该架构可以很好地验证上述 XML。可悲的是,xsd.exe 和其他一些工具报告它是一个错误。那是对的吗? XML 模式是否不允许循环组引用?谢谢!

更新:架构不是我的,无法更改:(

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:t="http://www.fixprotocol.org/ns/fast/t/1.0">

  <xs:element name="elem1">
    <xs:complexType>
      <xs:group ref="t:grp1" />
   </xs:complexType>
  </xs:element>

  <xs:group name="grp1">
    <xs:sequence>
      <xs:group ref="t:grp2" />
    </xs:sequence>
  </xs:group>

  <xs:group name="grp2">
    <xs:sequence>
      <xs:element minOccurs="0" name="elem2">
        <xs:complexType>
          <xs:group ref="t:grp1" />
        </xs:complexType>
      </xs:element>
    </xs:sequence>
  </xs:group>

</xs:schema>

【问题讨论】:

  • xsd.exe 的错误是什么?
  • 错误:为架构“tmp”生成类时出错。 - 来自 targetNamespace='...' 的组 'grp2' 的定义无效:循环组引用。如果这是一个 XSD 错误,我可以尝试联系负责它的组织,并告诉他们一个错误。如果没有,我会尝试寻找替代代码生成器,或者尝试修复 mono 的 xsd.exe 中的错误(挂起而不是显示错误)。

标签: xsd xsd.exe circular-reference


【解决方案1】:

这个问题与最近讨论相同问题的许多问题相关联:循环组和 Microsoft 的 xsd.exe,因此我认为应该回答它,即使它很“旧”。

混淆是由符合循环组的条件引起的。根据3.8.6 of the XSD 部分规范:

"不允许使用圆形组。也就是说,在 a 的 {particles} 内 在任何深度都不能有一个粒子,其 {term} 是 组本身。”

基于上述,您的示例不是循环群,因为该群本身并不依赖于自身作为粒子。您的架构有效

这是一个循环群:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns="http://www.fixprotocol.org/ns/fast/t/1.0" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="elem1">
        <xsd:complexType>
            <xsd:group ref="grp1"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:group name="grp1">
        <xsd:sequence>
            <xsd:choice>
                <xsd:group ref="grp1"/>
            </xsd:choice>                       
        </xsd:sequence>
    </xsd:group>
</xsd:schema>

无法重写真正的循环群。但是,您的示例可以通过多种方式重写:下面的架构显示了基于递归复杂类型的等效内容模型。

<?xml version="1.0" encoding="utf-8" ?>
<!-- XML Schema generated by QTAssistant/XSD Module (http://www.paschidev.com) -->
<xsd:schema xmlns="http://www.fixprotocol.org/ns/fast/t/1.0" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:annotation>
        <xsd:documentation xmlns="">Generated from "Set1" under "Release2"</xsd:documentation>
    </xsd:annotation>

    <xsd:complexType name="grp1">
        <xsd:sequence>
            <xsd:element minOccurs="0" name="elem2" type="grp1"/>
        </xsd:sequence>
    </xsd:complexType>

    <xsd:element name="elem1" type="grp1"/>
</xsd:schema> 

看到以下架构实际上与 xsd.exe 一起工作也很“有趣”:

<?xml version="1.0" encoding="utf-8"?>
<!--XML Schema generated by QTAssistant/XML Schema Refactoring (XSR) Module (http://www.paschidev.com)-->
<xsd:schema xmlns="http://www.fixprotocol.org/ns/fast/t/1.0" attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.fixprotocol.org/ns/fast/t/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:annotation>
        <xsd:documentation xmlns="">Generated from "Set1" under "Release2"</xsd:documentation>
    </xsd:annotation>
    <xsd:element name="elem1">
        <xsd:complexType>
            <xsd:group ref="grp1"/>
        </xsd:complexType>
    </xsd:element>
    <xsd:group name="grp1">
        <xsd:sequence>
            <xsd:element minOccurs="0" name="elem2">
                <xsd:complexType>
                    <xsd:group ref="grp1"/>
                </xsd:complexType>
            </xsd:element>
        </xsd:sequence>
    </xsd:group>
</xsd:schema>

从 XML 实例的角度来看,所有三个有效模式都是等效的。

【讨论】:

    【解决方案2】:

    问题可能是您使用的工具不支持 XML 模式规范支持的所有可能性。当然 xsd.exe 并不支持所有内容。该规范非常庞大,不值得提供从它支持的所有内容到编程语言的映射,尤其是当有些东西映射得不是很好时。

    要解决此问题,您可以尝试创建一组模仿您要生成的 xml 的 C# 类,然后在这些类上运行 xsd.exe 以生成 xsd。可能还有一些其他 XML 模式构造支持您想要的。

    【讨论】:

    • 是的,大卫,这就是问题所在,但我需要确定 XSD 规范是否允许,并可能帮助 Mono 团队解决这个问题(他们的 xsd.exe 工具挂起)。我希望我可以更改架构,但像往常一样 - 它是来自组织的公共架构,而不是我的 :)。我试图阅读规范,但对他们的语言感到非常困惑,所以希望有人知道答案。
    【解决方案3】:

    这是一个合法的计划。问题是 xsd 正在尝试遍历所有依赖项。 MS 版本预处理方案并扩展所有组。由于循环依赖,这种扩展将是无限的,因此它会因错误而退出。 Mono 版本有两种可能的情况:

    1. 它试图遍历依赖树 并最终陷入无限循环。
    2. 它会尝试扩展所有组并 最终陷入无限循环。

    这只是我的猜测。我从未见过 Mono xsd 的实际源代码。

    【讨论】:

    【解决方案4】:

    我不了解组,但 XSD.exe 支持循环元素:

    <xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="Class1" nillable="true" type="Class1" />
      <xs:complexType name="Class1">
        <xs:sequence>
          <xs:element minOccurs="0" maxOccurs="1" name="Name" type="xs:string" />
          <xs:element minOccurs="0" maxOccurs="1" name="child" type="Class1" />
        </xs:sequence>
      </xs:complexType>
    </xs:schema>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-22
      • 1970-01-01
      • 2015-12-22
      • 2011-02-21
      • 2018-07-16
      • 1970-01-01
      • 2019-09-30
      • 1970-01-01
      相关资源
      最近更新 更多