如何在xsd模式中定义XML元素,该元素可以包含一个属性还是其他几个属性?

时间:2013-04-09 10:51:48

标签: xml xsd

我在我的项目中使用MVVM模式。我通过XML描述了一个视图。但是我需要将它拆分成几个XML文件,因为一个XML文件太大了。

当我的解析器读取XML时,它首先找到“Source”属性。如果存在,解析器将加载其他XML文档并从此文档中读取元素。否则,如果“Source”属性不存在,则解析器会读取其他属性。

Source属性的示例:

<RibbonDefaultPageCategory>
  <RibbonPage
    Source="DefaultPageCategory/RibbonPage.xml"/>
</RibbonDefaultPageCategory> 

没有Source属性的示例:

<RibbonDefaultPageCategory>
  <RibbonPage
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="_Schema.xsd"
    RibbonPageTitle="RibbonPageTitle">
     ...
   </RibbonPage>

是否可以在XML模式中定义此行为?也许可以使用XML Element而不是属性?

喜欢这个

<ExternalElement
    ElementName="RibbonPage"
    Path="DefaultPageCategory/RibbonPage.xml"/> 

2 个答案:

答案 0 :(得分:2)

使用属性是不可能的,但可以使用元素。像这样:

<xs:element name="RibbonPage">
  <xs:complexType>
    <xs:choice>
      <xs:element name="Source" type="xs:string"/>
      <xs:sequence>
        <xs:element name="RibbonPageTitle" type="xs:string"/>
        <!--
           ...place here the definiton of other elements defining the properties of 'RibbonPage'
        -->
      </xs:sequence>
    </xs:choice>
  </xs:complexType>
</xs:element>

验证

<RibbonPage>
  <Source>...</Source>
</RibbonPage>

<RibbonPage>
  <RibbonPageTitle>...</RibbonPageTitle>

</RibbonPage>

但同时不允许SourceRibbonPageTitle

另一种方法是使用两个不同的元素名称 - 例如{4}当定义在其他地方时RibbonPageRef当值在元素本身正确时RibbonPage

<xs:element name="RibbonDefaultPageCategory">
  <xs:complexType>
    <xs:choice>
      <xs:element name="RibbonPageRef">
        <xs:complexType>
          <xs:attribute name="Source" type="xs:string"/>
        </xs:complexType>
      </xs:element>
      <xs:element name="RibbonPage">
        <xs:complexType>
          <xs:attribute name="RibbonPageTitle" type="xs:string"/>
          <!--
             ...
          -->
        </xs:complexType>
      </xs:element>
    </xs:choice>
  </xs:complexType>
</xs:element>

以这种方式有效的XML文件是:

<RibbonDefaultPageCategory>
  <RibbonPageRef Source="..."/>
</RibbonDefaultPageCategory>

<RibbonDefaultPageCategory>
  <RibbonPage RibbonPageTitle="..."/>
</RibbonDefaultPageCategory>

答案 1 :(得分:0)

人们经常忽略在模式验证之前进行转换的可能性。当您拥有处理管道时,在验证步骤之前进行某种“规范化”步骤通常是合理的。主要的缺点是,根据源文档找出验证错误的原因将更加困难。