XSD使用choice of attributeGroup验证xml

时间:2015-11-24 09:52:27

标签: xml xsd

问题描述:

我必须选择为现有的Value元素添加一组属性(见下文)。

sourceMsgType(必需),sourceMsgVersion(可选),destinationMsgType(必需),destinationMsgVersion(可选)或suppressSource(必需),suppressMsgVersion(可选)将出现。

我尝试使用以下XSD,但它显示以下错误:

"**S4s-elt-invalid-content.1: The Content Of '#AnonType_messageTypearchiveConfig' Is Invalid. Element 'choice' Is Invalid, Misplaced, Or Occurs Too Often.**". 

请帮帮我。提前谢谢。

XML

<?xml version="1.0" encoding="UTF-8"?>
<archiveConfig>
     <archivingStrategy>PURGE</archivingStrategy>
     <messageType sourceMsgType="STL01" sourceMsgVersion="" destinationMsgType="195" destinationMsgVersion="01" cutOff="90" filter ="N"/>
     <messageType sourceMsgType="STL01" destinationMsgType="CHESS197_01" cutOff="180"/> 
     <messageType sourceMsgType="STL03" destinationMsgType="101" destinationMsgVersion="02" cutOff="60" filter ="Y"/>
     <messageType suppressedSource="STL03" cutOff="60" filter ="Y"/>
     <messageType suppressedSource="STL01" suppressedMsgVersion="01" cutOff="60" filter ="Y"/>
</archiveConfig>

XSD

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" 
  elementFormDefault="qualified" 
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
  vc:minVersion="1.1">
  <xs:element name="archiveConfig">
    <xs:complexType>
      <xs:sequence>
        <xs:element type="xs:string" name="archivingStrategy"/>
        <xs:element name="messageType" maxOccurs="unbounded" minOccurs="1">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                    <xs:attribute type="xs:short" name="cutOff" use="required"/>
                    <xs:attribute type="xs:string" name="filter" use="optional"/>
                    <xs:choice minOccurs="1" maxOccurs="unbounded">
                    <xs:attributeGroup ref="setOfAttrs1" />
                    <xs:attributeGroup ref="setOfAttrs2" />
                    <xs:assert test="(@sourceMsgType and @destinationMsgType 
                    and (@sourceMsgVersion or not(@sourceMsgVersion)) and (@destinationMsgVersion 
                    or not(@destinationMsgVersion)) not(@suppressedSource) and not(@suppressedMsgVersion))
                    or (@suppressedSource and (@suppressedMsgVersion or not(@suppressedMsgVersion)) 
                    and not(@sourceMsgType) and not(@sourceMsgVersion) and not(@destinationMsgType) and not(@destinationMsgVersion))"/> 
                </xs:choice>  
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
  <xs:attributeGroup name="setOfAttrs1">
    <xs:attribute type="xs:string" name="sourceMsgType" use="required"/>
    <xs:attribute type="xs:string" name="sourceMsgVersion" use="optional"/>
    <xs:attribute type="xs:short" name="destinationMsgType" use="required"/>
    <xs:attribute type="xs:byte" name="destinationMsgVersion" use="optional"/>
  </xs:attributeGroup>
  <xs:attributeGroup name="setOfAttrs2">
    <xs:attribute type="xs:string" name="suppressedSource" use="required"/>
    <xs:attribute type="xs:string" name="suppressedMsgVersion" use="optional"/>
  </xs:attributeGroup>
</xs:schema>

1 个答案:

答案 0 :(得分:0)

你的xsd中存在许多问题,但它们都来自一个不正确的假设。您假设xs:choice可以包含属性组。

事实上,选择组是一种模型组&#39;和模型组只能包含元素,组和通配符。不是属性。详细信息都在XML Schema规范中。它不容易阅读,但它是这样的问题的最终权威:http://www.w3.org/TR/xmlschema11-1/

因此,您无法达到您所寻求的确切验证规则,但您应该能够接近。只需使一些属性可选。如果您需要严格验证规则,则需要执行以下操作之一:

  • 在您的应用程序中添加验证逻辑以强制执行规则
  • 使用更强大的XML验证语言(例如schematron / RelaxNG)

或者,只有在您控制的XML格式下,您才能执行以下任何操作:

  • 使用标签代替属性来建模这些属性。然后,您将能够使用包含xs:choice中元素的模型组。
  • 为messageType的两个变体(messageType1和messageType2)
  • 定义不同名称的标记
  • 如果对两个变体使用相同的标记名称很重要,则定义两个全局复杂类型,它们都是基本复杂类型的扩展。然后,XML中的 通过添加指定复杂类型名称的xsi:type属性来标识要验证的复杂类型。