为什么VisualStudio 2017告诉我“......在这种情况下不支持元素”?

时间:2018-03-29 01:30:53

标签: visual-studio xsd

MCVE:

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema 
    targetNamespace="http://versionschema.org/xmlns/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:vs="http://versionschema.org/xmlns/"
    elementFormDefault="unqualified"
    attributeFormDefault="unqualified">

    <xsd:element name="VersionSchema" type="vs:VersionSchema"/>

    <xsd:complexType name="VersionSchema" minOccurs="1" maxOccurs="1">
    <!-- VS says: "minOccurs and maxOccurs not allowed ^^^^ -->

        <xsd:element name="Field" minOccurs="1" maxOccurs="unbounded">
          <!-- ^^^ VS says: The 'http://www.w3.org/2001/XMLSchema:element' is not supported in this context -->
        </xsd:element>

    </xsd:complexType>

</xsd:schema>

参考https://www.w3.org/TR/xmlschema-0/#POSchema,我不明白为什么抱怨。是否有什么想法我在这里做错了什么?

请注意,我的目标是编写它,以便XML文件中只能有一个VersionSchema对象。

1 个答案:

答案 0 :(得分:1)

您正在从编程语言的角度考虑这一点,您可以通过将字段作为元素放在容器内来将字段添加到类或类型中。

对于XML Schema,这不是真的。原因在于,在最严格的定义中,XML依赖于顺序。

您可以自己编写一个接受以下XML的模式。

<Root>
    <Element/>
    <Test/> 
</Root>

但拒绝一个非常类似的XML结构:

<Root>
    <Test/>
    <Element/>
</Root>

您可以这样做的原因之一是因为更严格的XML架构更容易防范攻击和恶意输入。因此,总是需要在XML Schema中指定元素看起来是否重要的​​顺序。这就是需要诸如xsd:sequence之类的元素的原因。请注意,这很快就会成为序列化和反序列化的绊网。

因此,您的原始XML可以如下陈述,但根据您的具体用例可能会有不同的说明

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema
  targetNamespace="http://versionschema.org/xmlns/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:vs="http://versionschema.org/xmlns/"
  elementFormDefault="unqualified"
  attributeFormDefault="unqualified">

  <xsd:element name="VersionSchema" type="vs:VersionSchema"/>

  <xsd:complexType name="VersionSchema">
    <xsd:sequence minOccurs="1" maxOccurs="1">
      <xsd:element name="Field" minOccurs="1" maxOccurs="unbounded"></xsd:element>
    </xsd:sequence>
  </xsd:complexType>
</xsd:schema>

相关部分为3.4 Complex Type Definitions2.2.3 Model Group Components。它说明了

  

复杂类型定义架构组件的XML表示形式   是<complexType>元素信息项。 [...]内容:

(annotation?, (simpleContent | complexContent | (openContent?, (group| all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*)))

请注意,要将<element>放入复杂类型,您必须使用complexContentgroup或模型组元素,例如all,{{1} }或choicesequence不能包含complexContent但仅包含<element>只能包含<{p}}的内容相同

extension
  

[...]模型组有三种变种:

     

序列(元素信息项与粒子匹配)   顺序);连词(元素信息项匹配   颗粒,任何顺序);分离(元素信息   项目匹配一个或多个粒子)。模型组,一种术语   [...]指定顺序(序列),析取(选择)或   {particle}的联合(全部)解释。这反过来   确定元素信息项[children]是否有效   由模型组必须:

     

(序列)按顺序对应于指定的{粒子};   (选择)恰好对应于指定的{粒子}之一; (所有)   对应于指定的{粒子}。元素可以出现在任何元素中   顺序。

即使在模型组部分中略微混淆,模型组本身也只能托管以下内容

(annotation?, openContent?, ((group | all | choice | sequence)?, ((attribute | attributeGroup)*, anyAttribute?), assert*))

当你想使用(annotation?, (all | choice | sequence)?) 时,必须使用所有,选择和顺序。

  • all :(注释?,(元素 | any | group)*)
  • 选择:(注释?,(元素 | group | choice | sequence | any)*)
  • 序列:(注释?,(元素 | group | choice | sequence | any)*)