如何在xsd模式中定义可包含一个属性或其他几个属性的XML元素?

问题描述:

我在我的项目中使用MVVM模式。我通过XML描述了一个视图。但是我需要把它分成几个XML文件,因为一个XML文件太大了。如何在xsd模式中定义可包含一个属性或其他几个属性的XML元素?

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

例与来源属性:

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

例无来源属性:

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

是否可以定义XML模式这种行为?也许有可能使用XML元素而不是属性?

像这样

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

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

<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

另一种方法是使用两个不同的元素名称 - 例如, 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> 

人们常常忽略这样做之前,模式验证转换的可能性。当你有一个处理流水线时,在验证步骤之前进行某种“标准化”步骤通常是非常合理的。主要缺点是根据源文档找到验证错误的原因会更困难。