如何在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>
,但不允许在同一时间都Source
和RibbonPageTitle
。
另一种方法是使用两个不同的元素名称 - 例如, 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>
答
人们常常忽略这样做之前,模式验证转换的可能性。当你有一个处理流水线时,在验证步骤之前进行某种“标准化”步骤通常是非常合理的。主要缺点是根据源文档找到验证错误的原因会更困难。